Skip to content

1. Syntax

Marek Poláček edited this page Jul 26, 2019 · 10 revisions

Kris-Kros game map is consisting of two files combo: there's an index table file in ZSoft PC Paintbrush (PCX) format, and a text interpretation of this index table. One cannot exist without another. When the game app starts, the index PCX file is loaded first, then the text interpretation holding additional informations, which specify what belongs to which coordinates. These coordinates correspond to the PCX index map. If the table size does not correspond to the PCX image dimensions or the PCX image is in incorrect format, the game unloads both files from memory and ignores them. If both tables are correct and correspond with each other, their location or resource identifier is saved into memory and later called when needed.

How the game exactly interprets the index table? Read on...

1.1. PCX index map format

First of all, there's a PCX index map file. It's pretty much normal image in PCX format. Just one thing: The image has to be exactly in 4bit color depth format (16 colors). Any else format results in incorrect format and the map is not loaded. Not all indexes are used, though. Only the first 10 indexes of all 16 are used. Indexes are numbered starting from 0, which is pretty much standard in all programming languages. Colors are irrelevant, because indexes are what we're interested in. Usable index value is in range 0-9 (remember, we count from 0).

Each index value is assigned to certain field type. Pixels of PCX image are then represented as cells of the game table that is displayed. There are 10 types of field types:

#define ILLUSTRATION_FIELD      0     // Illustration occupied field
#define FILL_FIELD              1     // Field for filling (normal game field)
#define SOLUTION_CONTINOUS      2     // Field for continuing piece of solution (second and next letter in order)
#define SOLUTION_FIRST_LEFT     3     // Field for first letter of piece of solution from left
#define SOLUTION_FIRST_TOP      4     // Field for first letter of piece of solution from top
#define CAPTION_SINGLE          5     // Field for single caption (eighter from left or top, not both)
#define CAPTION_DOUBLE          6     // Field for double caption (top = word from left, bottom = word from top)
#define DECORATION_FIELD_A      7     // Field for decoration (empty field, no function), var.A
#define DECORATION_FIELD_B      8     // Field for decoration (empty field, no function), var.B
#define AIDS_FIELD              9     // Field for aid words (words aiding in solving the Kris-Kros)

No more indexes are defined. Caption fields are only informative. No special check is done while interpreting these fields. If you want to make an impossible Kris-Kros, it's possible to completely omit the caption fields. Colors are irrelevant, because the index values are what game is looking for. Not every index in range 0-9 is required to interpret the image. But index beyond that range will cause an error and this image will be then ignored and unloaded from memory. Correct PCX image data will be saved in memory to later load up the text interpretation of the game table.

1.2. Text map format

PCX index map image file isn't the only one necessary entrance to display a game table. Since it is only an image, it can only provide general layout (dimensions of the image in pixels are dimensions of the table in cells, or how we call them fields, since it is a game table) and general information about the type of each field. It cannot hold any additional and pretty much required informations, like the correct letters in fields, captions, the solution, aid words and additional informations, like general caption (which is used for anecdotes), footer (used for anecdote source) and any illustrations that may or may not be included in the image.

General specification

Everything is defined using square [] and curly {} brackets. Strings are enclosed in double quotes "". General syntax of text map interpretation is defined as [TAG]=[CONTENT].

Entire map is enclosed by an opening and closing tags. Those tags are [BEGINMAP] and [ENDMAP] respectively. Their usage are to enclose map data. Everything outside those enclosing tags is considered a comment and therefore ignored in parsing phase. If you need to specify a comment inside the map, use [COMMENT] tag as follows: [COMMENT]=["comment content"], where comment content is anything you like. This tag is parsed as comment and unloaded from memory and further ignored. Inside enclosing tags, there can be any amount of empty lines, they are treated as comments. Tags cannot contain a line break, however. If you need to enter a line break or special characters to strings, use escape sequences:

  • \n for line break
  • \t for tabulator/indent
  • \\ for backslash \

While [ENDMAP] tag is on its own, [BEGINMAP] tag contains more informations (and actually most informations than any other tag). The opening tag has following syntax:

[BEGINMAP]=[PCX:"file.pcx";LANG:"language-code";CAPTION:"file.txt";FOOTER:"file.txt"]

Anything noted as file.ext (where ext is file extension) are relative or absolute paths to files used in this map. PCX entry is used for the map PCX image entry to use a PCX image of different file name than the text map specification. CAPTION entry is used for including a caption defined inside the included file, which is in plain text format with additional markup language. Caption is actually used for additional text and may contain placeholder(s) for solution. Multiple placeholders can be used in this file. A placeholder is defined using an XML tag <sol></sol>, which means solution. If you need to use the <> characters as they are (without interpretation), escape them using backslash \. If you need to use the backslash \, you have to escape it: \\. Inside solution placeholder, there can be any sequence of characters (except for the solution XML tag), only letters are actually taken. FOOTER entry is used for including a footer defined inside the included file, which is pure plain text format, without any formatting.

Remaining entry is used to define the language of the map (LANG). This is actually a string, but only two values are currently supported:

  • cz for Czech language
  • en for English language

Any other language is currently not supported. If you want your language to be supported, let me know. I'll definitely add also German, French and Russian languages as the international languages in next versions (will be announced ahead), and I also considered adding Polish and Slovak languages, because those countries are my neighbours. However, I'll need an aid of dictionaries for these languages and very good resource of local anecdotes in these languages to include. You can contribute. Just let me know, add feature request in issues, or create a pull request, if you know, how to write it in code. For detailed pull request informations, please read project documentation.

The most important tag is the [INDEX] tag. This is the gate to the game. Its syntax actually varies a little bit. The actual syntax is actually index dependent. The general syntax of [INDEX] tag is as follows:

[INDEX]=[ID;CONTENT]
  • ID is the index in range 0-9
  • CONTENT is the index dependent syntax content

The index 0 (illustration occupied field) is a special one:

[INDEX]=[0;{Xstart,Ystart:Xend,Yend};"file.bmp"]
  • It's actually a rectangular set of fields of the table to display the linked illustration on:
    • Xstart and Ystart is top left coordinate of linked illustration image
    • Xend and Yend is bottom right coordinate of linked illustration image
    • The dimensions of the fields determine the viewport for the linked image. A single table cell (called field) is 49x49 pixels and neighbour cells are overlapped by 1 pixel. So the displayed image dimensions are X*49+1-X and Y*49+1-Y, while X=Xend-Xstart+1 and Y=Yend-Ystart+1.
    • file.bmp is the relative or absolute path to the illustration image to link. If the image isn't exactly the viewport size, it is cropped to center. The best results are achieved when the picture is using exact dimensions.
    • The viewport actually overlaps the game table grid and two or more sets of rectangular viewports can neighbour each other. That allows to conjunct different images to create more complex shapes than rectangles (e.g. a circle) by using multiple illustration images designed in such way that they together make up one big continuous or to create a complex collage of pictures.

Index 1 (fill field) and 2 (solution continued) have both same syntax:

[INDEX]=[ID;{X,Y};CH]
  • ID is the index number (1 or 2)
  • X and Y is the coordinate of the field
  • CH is the letter in that field

Index 3 (solution first left) and 4 (solution first top) also have both same syntax:

[INDEX]=[ID;{X,Y};CH;NUM]
  • ID is the index number (3 or 4)
  • X and Y is the coordinate of the field
  • CH is the letter in that field
  • NUM is the solution piece number (any number can be specified, the order of the solution pieces is from lowest number to highest)

Index 5 (caption single) and 6 (caption double) have similar syntax:

[INDEX]=[5;{X,Y};"caption"]
[INDEX]=[6;{X,Y};{"top caption","bottom caption"}]
  • Both types have the X and Y coordinate of the field specified the same way
  • The only difference is between the caption interpretation:
    • Index 5 has only one single caption for word eighter from left or top
    • Index 6 has a top caption for word from left and bottom caption for word from top

Index 7 and 8 (decorative fields variants A and B respectively) do not have any additional information, they serve no function at all, only to fill unused fields. So their syntax is most straightforward:

[INDEX]=[ID;{X,Y}]
  • ID is the index number (7 or 8)
  • X and Y is the field coordinate

And the last index is 9 (aids field). This one has somewhat complicated syntax:

[INDEX]=[9;{X,Y};{{X,Y}:length+dir,...}]
  • First occurance of X and Y (right after index number) is the aids field coordinate. If there is such field specified, it should be only specified once. Two or more occurances of this field will actually result in an error, both in PCX and the text interpretation. An error actually results in ignoring entire map.
  • Second and next occurences of X and Y coordinates (after the aids field coordinates) specify each aid word starting point - a field coordinate of a first letter of that aid word. The next statement needs a little bit more explanation:
    • length is a number that specifies the length of the word (how many letters does the word have)
    • dir is the direction and is specified by a single character (a character in terms of programming, not a letter):
      • L specifies direction from left (the word is horizontal)
      • T specifies direction from top (the word is vertical)
    • length and dir are NOT actually separated by a plus + character, they are written together:
      • 9T specifies length of 9 letters from top
      • 5L specifies length of 5 letters from left
  • Each of these statements are members of an array of those statements. Please note that when an aids field is defined, at least one aid word should be specified. Otherwise it's an error. An aids field is typically in top left corner of the table.

The aids field may appear like this:

[INDEX]=[9;{0,0};{{5,3}:8L,{7,1}:4T}]
  • Aids field is located at 0,0 coordinate (top left of the game table)
  • First aid word starts at coordinate 5,3 and is 8 letters long from left
  • Second aid word starts at coordinate 7,1 and is 4 letters long from top
  • Note that it does not specify the words explicitly. It actually takes the letters outside from fields and display them as words inside this field. That also applies to using these aid words to help youself to win the game. Filling them on your own do not automatically cross the aid word, because technically you didn't use them. Using them will cross them and automatically fill the corresponding fields for you instead.
  • Make sure that the first letter is really first letter. That means that the field right next to left or right above should be other type, than a fill field (solution fields are also considered fill fields in this case). Ideally, it should be eighter single or double caption field. Also make sure that the last letter is right next to the other type field (not a fill field), also ideally a caption field (same as with first letter). If one or the other criteria is not met, this is an error and the game table is ignored completely.

Summary of the text map interpretation syntax on following example (this is actually first table in the game):

Anecdote (Czech) #1: "Murphy's Law"
[BEGINMAP]=[PCX:"kros0001.pcx";LANG:"cz";CAPTION:"cap0001.txt";FOOTER:"foot0001.txt"]
[COMMENT]=["Aids field --> PTA, PRV"]
[INDEX]=[9;{0,0};{{6,1}:3L,{1,2}:3L}]
[INDEX]=[5;{1,0};"SLUŽBA\nSERVI-\nSU"]
[INDEX]=[5;{2,0};"1. DÍL\nTAJEN-\nKY"]
[INDEX]=[5;{3,0};"MUŽ.\nJMÉNO"]
[INDEX]=[8;{4,0}]
[INDEX]=[7;{5,0}]
[INDEX]=[5;{6,0};"POKRÝV-\nKA"]
[INDEX]=[5;{7,0};"TAK\nMOC"]
[INDEX]=[5;{8,0};"CITOSL.\nPOCHO-\nPENÍ"]
[INDEX]=[7;{9,0}]
[INDEX]=[8;{10,0}]
[INDEX]=[5;{11,0};"HLAS.\nČIN-\nNOST"]
[INDEX]=[5;{0,1};"ZNAČKA\nAUTO-\nMOBILU"]
[INDEX]=[1;{1,1};O]
[INDEX]=[4;{2,1};P;1]
[INDEX]=[1;{3,1};E]
[INDEX]=[1;{4,1};L]
[INDEX]=[5;{5,1};"MEZ.\nZPR. A.\nZKR."]
[INDEX]=[1;{6,1};P]
[INDEX]=[1;{7,1};T]
[INDEX]=[1;{8,1};A]
[INDEX]=[5;{9,1};"SPORT.\nZKR."]
[INDEX]=[7;{10,1}]
[INDEX]=[1;{11,1};Z]
[INDEX]=[5;{0,2};"PROG.\nROZV.\nVEN.ZK."]
[INDEX]=[1;{1,2};P]
[INDEX]=[2;{2,2};R]
[INDEX]=[1;{3,2};V]
[INDEX]=[8;{4,2}]
[INDEX]=[5;{5,2};"CITOSL.\nVINY"]
[INDEX]=[1;{6,2};O]
[INDEX]=[1;{7,2};U]
[INDEX]=[1;{8,2};H]
[INDEX]=[1;{9,2};A]
[INDEX]=[5;{10,2};"VÝMĚ-\nŠEK"]
[INDEX]=[1;{11,2};P]
[INDEX]=[5;{0,3};"OKRAS.\nKVĚTI-\nNA"]
[INDEX]=[1;{1,3};R]
[INDEX]=[2;{2,3};Ů]
[INDEX]=[1;{3,3};Ž]
[INDEX]=[1;{4,3};E]
[INDEX]=[6;{5,3};{"2.DÍL\nTAJEN.","MĚSTO\nZÁP.Č."}]
[INDEX]=[3;{6,3};V;2]
[INDEX]=[2;{7,3};Z]
[INDEX]=[2;{8,3};Á]
[INDEX]=[2;{9,3};C]
[INDEX]=[2;{10,3};P]
[INDEX]=[2;{11,3};Ě]
[INDEX]=[5;{0,4};"CITOSL.\nZVOLÁ-\nNÍ"]
[INDEX]=[1;{1,4};A]
[INDEX]=[2;{2,4};J]
[INDEX]=[1;{3,4};E]
[INDEX]=[6;{4,4};{"SPOJKA","UNIV.\nKAR.ZK."}]
[INDEX]=[1;{5,4};A]
[INDEX]=[1;{6,4};L]
[INDEX]=[1;{7,4};E]
[INDEX]=[5;{8,4};"EVR.\nUNIE\nZKR."]
[INDEX]=[6;{9,4};{"SPZ\nOSTR.","NÁZEV\nPÍSM. M"}]
[INDEX]=[1;{10,4};O]
[INDEX]=[1;{11,4};V]
[INDEX]=[5;{0,5};"PLA-\nNETA"]
[INDEX]=[1;{1,5};V]
[INDEX]=[2;{2,5};E]
[INDEX]=[1;{3,5};N]
[INDEX]=[1;{4,5};U]
[INDEX]=[1;{5,5};Š]
[INDEX]=[1;{6,5};E]
[INDEX]=[5;{7,5};"ELEKT.\nEV.TRŽ.\nZKR."]
[INDEX]=[1;{8,5};E]
[INDEX]=[1;{9,5};E]
[INDEX]=[1;{10,5};T]
[INDEX]=[8;{11,5}]
[INDEX]=[5;{0,6};"AMPL.\nMOD.\nZKR."]
[INDEX]=[1;{1,6};A]
[INDEX]=[2;{2,6};M]
[INDEX]=[7;{3,6}]
[INDEX]=[1;{4,6};K]
[INDEX]=[7;{5,6}]
[INDEX]=[1;{6,6};K]
[INDEX]=[5;{7,6};"SCHOP-\nNOST"]
[INDEX]=[1;{8,6};U]
[INDEX]=[1;{9,6};M]
[INDEX]=[8;{10,6}]
[INDEX]=[7;{11,6}]
[COMMENT]=["End of entire map"]
[ENDMAP]
::: EOF

1.3. Program Resources

To use resources provided by the program, file names will actually start with *$ sequence and eighter used a numbered sequence, or resource symbol:

[BEGINMAP]=[PCX:"*$PCX0001";LANG:"en";CAPTION:"*$CAP0001";FOOTER:"*$FOOT0001"]
[INDEX]=[0;{5,0:7,4};"*$IM0001"]

What it does is that if it is a number, it looks directly for a specified resource ID number. If it is a symbol, it tries to resolve it to a resource ID number and look for resolved resource ID number. This makes it possible to create variations of the already contained Kris-Kros and this is actually the engine that drives the game.


Read also section #2 to learn about means to create own game boards through following a small tutorial.