Welcome to the fifth part of my updated Skinning Guide for FM2015.
Before reading this guide make sure you have read the previous parts of the guide as well as the extracting files guide, as this guide will assume you have followed those guides.
The previous parts of the guide talked you through creating a new skin, changing the fonts, changing some of the font settings and colours, with the last part detailing how to change the skin graphics.
This part of the guide will talk you through some of the basics of how the xml files work. Due to how Football Manager works it isn't possible to give you a full guide on how to edit the xml files however this guide should give you some basic information to get you started. I also have some more detailed posts on this forum/my website that talk you through modifying certain screens and if you combine those guides with the basics learned here you should get a good understanding of how the xml coding in Football Manager works, after that the best way to learn is just from the experience of looking through and editing the xml files.
Editing the xml files is fairly simple once you know where to start and as such it doesn't actually require any coding experience, though some very very basic knowledge of coding or even webpage editing will give you a quicker start (even the simple knowledge of how to manually format your posts when posting on the forum is all you really need to start with).
You should also only rarely need to actually write your own xml code, most if not all of your xml editing will involve copying code from one place/file to another to change where it displays or will involve deleting of some code if you want to hide certain things, so you mainly need to know how the code links together and what is part of the same code. The hardest thing you'll probably have to do is to adjust the code you copied so it matches the format of the existing code as the code can change slightly depending on where and how it's displayed.
Before starting I advise you have the following folder locations open:
- Your 'Working' Folder Location from the previous guide (which is where you extracted the default game files to).
- The my_first_skin folder within your Saving Location.
You will also need to have your preferred xml file editor open as well as FM2015.
The basics of the xml file
The basics of the xml file
Before you start editing the xml files you need to understand how the files work on a basic level.
If you want some background information on xml coding in generally then check out the XML Tutorial offered by w3schools.com – though for FM purposes you only really need to know the first few chapters anything past the Attributes chapter isn't really needed for FM.
The first thing you need to know is there are three kinds of tags you'll come across in the xml files;
</record>
<record/>
The first one <record> is an opening tag this starts off some code which is then closed by the second tag </record> which is a closing tag.
For each <record> tag that you have you also need to have a </record> tag in the file as the opening and closing tags must always balance, if you don't balance the tags you'll get an error in game.
In addition a closing tag will only close a tag of the same name so a closing tag </string> will not close or balance out a <record> tag to close the <record> tag you need a </record> tag. A </string> tag will only close a <string> tag.
The third tag <record/> is a self-contained tag it opens and closes itself and as such doesn't need to be balanced.
For a simple example open up the 'skins\my_first_skin\skin_config' xml file.
On the second line you'll see a <record> tag this opens up a record element.
In the middle of the file you'll notice several lines like these:
<string id="name" value="My First Skin (Dark)" />
<string id="skin_name" value="my_first_skin" />
<string id="author" value="michaeltmurrayuk" />
<translation id="description" translation_id="249669" type="use" value="This is my first skin based on the Dark Default Skin" />
<string id="version" value="1.0" />
<flags id="parent" value="fm dark-widgets" />
All of these are self-contained tags, you'll notice that each of these have more than one word/element to them and in case of the translation one it might even be spread over more than one line yet they are all self-contained tags, that is because the tag type is only determined by the first word and by how the tag is opened and closed.
In this example we have three different elements; four string elements, a translation element and a flag element, these are determined by being the first word after the < which opens the element, and we know they are self-contained tags because the elements are closed by />
Finally at the bottom of the file we have a </record> tag which closes the record element, and balances out the file as we have one <record> tag and one </record> tag which opens and then closes a record element, with the rest of the tags being self-contained tags that don't need balancing.
The other thing you'll notice in this file are lines that contain <!-- and --> these are comment tags and work in the same way as the open and close tags, <!-- will open a comment and --> will close a comment, you'll notice that comments can either be contained to one line or span several lines.
Comments aren't read by the game but are notes for the user that will either contain notes about what a bit of code does or will disable some code. You can also add your own comments as you go to remind you what a certain piece of code does or id pertains to once you have worked it out, which can be handy if you come back to the file in the future and forgot what you had done to it.
The next thing you need to know about is nesting.
With the xml code you can nest elements within other elements of the same or different types. Nesting affects how various bits appear in the game and is used to group items together or to apply properties to a certain item. What you need to know at the moment is that nesting is affected by where you place the close tags within the xml file, so when messing around with the tags you'll need to ensure you place them in the correct place.
You can see a quick example of nesting by opening the 'my_first_skin\fonts\text' xml file that you should still have from a previous part of the guide, around the middle of the file you'll notice some code that looks like this:
<!-- shadowed style -->
<record style="shadowed">
<list id="shadows">
<record>
<integer id="x_offset" value="0"/>
<integer id="y_offset" value="1"/>
<integer id="blur_radius" value="2"/>
<integer id="colour_red" value="0"/>
<integer id="colour_green" value="0"/>
<integer id="colour_blue" value="0"/>
<integer id="colour_alpha" value="75"/>
</record>
</list>
</record>
The first line is a comment which lets us know the following code affects how the shadow on this text appears, the next line opens up a record element, then we open a list element and then open another record element, we then have seven self-contained integer elements, we then have a tag that closes one of the record elements, with the element it closing being the second one (<record>), we then close the list element before finally closing the remaining record element.
To simplify the above code opens up a record1 element, then a list element, then a record2 element (we can ignore the integer elements as they are all self-contained), it then closes the record2 element, then the list element before finally closing the record1 element.
You'll also notice that the <record style="shadowed"> element is closed by just a </record> tag this is because closing tags should only ever contain the one first word that determines the element type.
Element Types
The next thing you need to know are what the most common element types are and what they do.
Container
The container element as its name suggests acts as a container, these are mainly used to group bits of code, and you can also use blank containers to add some padding between items.
Widget
The widget element is used to display pretty much any kind of graphic or text in the game.
Layout
The layout element as its name suggests is used to position your containers and widgets on the screen. You'll quickly come to find this element rather frustrating as there are multiple layout attributes that often have to be used to together but it's not always clear which ones need to be used on certain screens or in certain places.
These are the three most common and basic elements used by Football Manager, however as you'll have seen from the previous examples there are also various other elements, however for the most part you won't need to adjust these unless you are doing something in particular (in which case the instructions will be covered in that particular guide) and if you do they act in the same way as these elements so once you have understand the basics of these three common elements you should be able to understand what the other elements do.
Element Attributes
Next up are the element attributes, if you refer to the following line in the 'my_first_skin\skin_config' xml file:
<string id="author" value="michaeltmurrayuk" />
By now you should recognize that this is a self-contained tag because it starts with < and ends with /> and as the first word is 'string' this is a string element.
The other items 'id' and 'value' are called attributes whilst the 'author' and 'michaeltmurrayuk' items are referred to as attribute values.
Element attributes always have to be formatted in the following format;
attribute="attribute_value"
The first word sets the attribute, you then follow this with an = and then place the attribute value inside " marks, if you don't do this correctly the game won't read the attribute and it will flag up an error. The = sign is telling the game to assign the following value to this attribute, whilst the " marks are needed to tell the game where the attribute value starts and ends as some attributes can contain more than one attribute value;
alignment="top, left"
In this example we are setting the alignment of something and we are wanting it to be in the top left position, so when including more than one attribute value for an attribute you separate them by a coma (,). The space after the coma is optional as the game will read both values without the space, the space just makes it easier for you to read.
You'll also notice quite often that you will have two related attributes following each other, in the first example the first attribute is telling the game we want to set the author variable and the value we are assigning it is my name (michaeltmurrayuk).
In the second example the alignment attribute will normally be followed by an inset code so it looks like this;
alignment="top, left" inset="10"
In this case we want to place something to the top left corner and want it to appear 10 pixels in from the top and left sides.
Attribute Types
There are countless attribute types that you can declare in the game, these attributes are used to apply properties to the various elements.
The attributes you can use are fixed as they are telling the game you want to set a certain attribute and as such the game needs to understand what attribute you are setting, whilst with attribute values you are generally free to put in what you want, though some attributes will only take certain values, but for the most part you can generally tell what values an attribute wants from its name.
What I am going to do now is talk you through some of the common attribute types for the three main elements (container, widget and layout).
First I want you to browse to the 'panels' folder inside your 'Working' folder and copy the 'player profile' xml file. We will use this file to get some examples from as it’s a relatively simple file and corresponds to a screen nearly everyone should know.
Now open the 'my_first_skin' folder in your Saving Location and if you haven't already create a new folder called panels and paste the 'player profile' xml file into this folder, so the panels folder of your 'my_first_skin' should now look like this:
Next load up Football Manager 2015 and set your skin to 'My First Skin (Dark)' and then browse to the Overview -> Attributes panel for any of your players.
Now open the copied 'player profile' xml file. I will use this file to run through some of the various attribute types you'll come across.
Container Attribute Types
If you look on line #23 you should see this code:
<container class="bordered_box" id="pdet" file="player profile personal details" />
The first attribute you will normally see is the class one this determines what kind of container we are wanting, and for containers the class determines the appearance of the container and you should remember from the graphics part of the guide that when we changed the attributes box graphic it didn't change the box around the profile, that is because as you can see this container is a bordered box whilst the attributes container was a subsection box. There are several different box types you can set the containers to (you can get a list of names from the subfolders listed in the skins\fm-widgets\graphics\boxes\ folder from your 'Working' folder). To change the type you just change the bordered bit to a different box, so if you want it to look like the attribute container change the above line to the following;
<container class="subsection_box" id="pdet" file="player profile personal details" />
Which should then look something like this in-game (if you haven't reverted the changes from the previous guides):
The main difference between the default subsection and bordered boxes is the fact that the subsection box has a space for a panel title whilst the bordered box doesn't. If you want you can experiment with the different styles to see what they look like, the two other types you'll normally come across are titled and plain with both of these giving you transparent panels one with space for a title and one without.
The next bit is the 'id' attribute which is used by the game to identify certain items, this can be a bit of a tricky one as some containers need a set id to display their contents correctly, others don't need one at all and in some cases the game needs each container to have its own unique id, for the most part you shouldn't need to adjust this, you only need to adjust this if you are using existing code as a template for something you have added.
The last attribute on this line is the 'file' attribute, this as the name implies is used to grab data from another file, in this case it Is telling the game to populate the contents of this container with the code found in the 'player profile personal details' xml file.
Now if you look on line #16 you will see the following different attributes for a container:
<container class="vertical_adaptive_container" id="PLPR" inset="0" offset="0" gap="8">
In this case we are still setting the class of the container but instead of just assigning it to a box we are setting it to something called a 'vertical_adaptive_container' and what this does is tell the game to change how many of the nested containers will appear on screen determined by our screen resolution, in this example we want to change the amount of vertical containers with the height of our screen, so if you are playing at a vertical resolution of 768 pixels you'll notice that we have the three classic rows of containers (Personal Details, Selection Details and Statistics) however if you increase your vertical resolution enough you'll notice that a fourth row (Positions) appears. There is also a 'horizontal_adaptive_container' class that operates in the same way but on the horizontal axis (think the Player Overview -> Profile screen).
The next attributes we are interested in on this line are the 'inset' and 'offset' attributes and these determine how close to the edge of the container the content and graphics will appear, in this case the inset value determines how many pixels from the left and right of the screen the nested containers content appears and the offset determines how many pixels from the top and bottom of the screen the content appears. If you play around with these values you'll notice that the position of the Attributes, Positions and Selection Details panels with respect to the edge of the screen changes, however you'll notice that the Statistics panel isn't affected, this is because it turns out the Statistics panel isn't nested within this vertical_adapative_container and as such isn't affected by any changes we make to this line of code. Note that the inset doesn't always just adjust the left/right margins and the offset doesn't always just adjust the vertical margins, how it acts depends on the element and preceding attributes, the quickest way to see what they actually do in other places is to adjust the values then reload your skin and see what direction the item has moved. You can also use negative numbers and these will shift the content the other way, in this case it will cause the content to start closer to the edge or even off the edge of the screen.
The final attribute on this line is the 'gap' attribute and this determines the spacing between each container in pixels, the higher the number the greater the gap between the panels and again you can use a negative number to bring them closer. Also note that this only affects the gap between the vertical panels it doesn't affect the gap between the horizontal panels.
Another type of container can be found on line #18;
<container default_height="384" priority="1">
These containers are used in conjunction with the adaptive containers, you'll notice in this case we haven't assigned the container a class that is because the class attribute isn't always needed for a container.
The 'default_height' attribute as the name suggests sets the height of the panel in pixels and the reason why this is needed is because this container is nested within the adaptive container, and for the adaptive container to work it needs to have the height of the various panels set so it knows if it can display them or not. There are two values the height attribute can take either a positive whole number which will set a height of that many pixels or you can also use a negative number, if you use a negative number it will tell the game to stretch this panel to fill up the remaining space, if there is more than one negative panel the number will determine the split as a ratio (more detail on this will be coming later).
In addition to the 'default_height' attribute there are also 'minimum_height' and 'maximum_height' attributes as well as 'default_width', 'minimum_width' and 'maximum_width' attributes for horizontal adaptive containers that all act in the same way. You can also combine these values to give your item a dynamic size depending on screen resolution, if you set both a default and maximum value then the game will display your item at the default size, but if it has space left it will expand up to the maximum size. Whilst if you set a minimum value then the game will only display the item if the available room is at least this amount.
The other attribute on this line is the 'priority' attribute which is again linked to the adaptive container, this attribute tells the game which containers to prioritize showing when there isn't enough space, and the lower the number the higher the priority, so a priority value of 1 means it will always show, which is why the Position and Form panels disappear at lower resolutions as they have a lower priority and there isn't enough room to show them.
Widget Attribute Types
To show some examples of the widget attribute types a better example to use is the 'match title bar score' xml file which is the file used to display the team names and scores on the match screen pitch when you have the titlebar hidden. First as an exercise I want you to locate and copy over the default file to the 'my_first_skin/panels' folder.
Now I want you to locate this code on line #25;
<widget class="text" id="Mclk" size="12" width="80" alignment="centre" style="semi_bold" colour="match text">
Like the container element the widget element starts with a 'class' attribute which determines what kind of widget we are going to be using, in this case we have a text widget which as the name implies is used to display some text on the screen.
The next attribute is the 'id' attribute and this tells us what kind of text to display in this case the id tells the game to display the match clock.
The next attribute sets the size of the text that displays, the 'width' attribute sets the width of the widget.
The 'alignment' attribute determines how the text is positioned in this case it is centred in the widget, you can also have it left or right aligned as well as top or bottom, you can also combine vertical and horizontal alignments to have "top, left" for example.
The 'style' attribute determines what style font is used (i.e. bold, italic, shadowed, embossed etc. Lists of styles can be found in the xml files in the fonts folder).
The 'colour' attribute sets the colour of the font; though note that this can in some cases be overridden by values set elsewhere or for some annoying items is hardcoded.
Another example for the widget can be found on line #38;
<widget class="picture" id="T1bp" auto_size="vertical" file="boxes/custom/match/scoreboard/team/paper" cached="true" rthr="68">
This case shows an example of the picture class widget, and again has similar attributes to the other elements, first the class tells us this is a picture, the id tells the game we want to display the home teams background colour.
The 'file' attribute tells the game what graphic to display, note that it doesn't need the graphics folder declared but it does need the subfolders inside the graphics folder declared and you also need to point to an actual graphic rather than just the folder.
The final attribute on this line we are interested in is the 'rthr' attribute and this is used when the game recolours a graphic from code, in this case the graphic becomes the home team background picture and is recoloured by the game to match the background colour of the home team.
There are a load more classes of widgets in the game but they generally work the same as these two, there are also a lot more attributes that can be applied to the widget elements, the easiest way to find these is to look through the xml files and look at the attributes assigned to the various widgets, most of them should have simple names that describe what they do.
Layout Attribute Types
Finally we are going to look at some of the attribute types for the layout element, now these can be fairly tricky to work out as you sometimes need to use combinations of them and different screens require different layout values, if you get stuck with these when moving items the best thing to do is to see how the elements near where you are placing your code is written and try and copy that, and if you are modifying items rather than moving them then the best method is to adjust the values of one attribute in the element and see what it does before adjusting another.
The below layout element is probably the most common one you'll come across;
<layout class="stick_to_sides_attachment" alignment="all" inset="2" />
The 'stick_to_sides_attachment' class tells the game to stick the related item (normally a container or widget) to the side of its parent.
The 'alignment' then tells the game what side to stick it to, with the 'inset' (or 'offset') attribute telling the game how far from the edge to stick the item.
In this example the inset value of two tells us we want the item stuck two pixels away from the side with the all alignment telling the game we want it stuck two pixels away from all the sides.
Inset and offset values have to be whole numbers but can be negative or positive.
Alignment values can also be top, bottom, left, right, horizontal or vertical; you can also combine them "top, left" or "top, right" etc.
Also if you want to have a different inset from different sides you can split the line up to read something like;
<layout class="stick_to_sides_attachment" alignment="top" inset="2" />
<layout class="stick_to_sides_attachment" alignment="right" inset="10" />
These set your item to appear two pixels in from the top and 10 pixels in from the right.
Another example line is;
<layout class="arrange_horizontal_attachment" offset="0" layout="-4, -6" gap="8" />
In this case the 'class' attribute means we have several items we want to display side-by-side; this is normally used when you are displaying multiple containers.
As the layout attribute has two values this means we have two items to show side by side, with the negative numbers meaning we want both of these items to scale with resolution rather than be a fixed size. With the actual numbers telling the game what ratio of space each item should take up. To calculate the ratios you add the two numbers together in this case we get 10 (4+6) which then gives you the ratio of each item, in this case the left item will take up 4/10 of the space whilst the right item will take up the remaining 6/10, if you want both items to use up the same space set them to the same value (-1 normally).
There is also an 'arrange_vertical_attachment' class that works in the same way but vertically rather than horizontally and will display items on top of each other.
The other layout class you will come across is this;
<layout class="fit_children_attachment" alignment="horizontal,fill" gap="0" offset="0" />
This class also tells the game you want to display several items one after another and is generally used for displaying multiple widgets. The alignment value this time determines how they appear, with a horizontal value setting them side-by-side and a vertical one putting them on top of each other, the fill value tells them to fill out the space one after another.
Summary
The container, layout and widget elements combine to form the vast majority of the coding in the xml files.
First you will generally call a container to group the content together, next you will use several layout elements to determine how the grouped content is laid out then finally you will use the widget elements to display an item in game before closing the container.
A full example of how each of these elements interacts can be found in the 'match title bar score' xml file;
<container class="bordered_box" appearance="boxes/custom/match/scoreboard/container/paper"><
<layout class="arrange_horizontal_attachment" alignment="horizontal" gap="0" offset="0" />
<layout class="fit_children_attachment" alignment="horizontal,fill" gap="0" offset="0" />
<layout class="stick_to_sides_attachment" alignment="vertical" layout_children="true" inset="0" />
<container width="10" />
<!--home button-->
<widget class="icon_button" id="homb" click_event="home" height="30" width="40" appearance="buttons/custom/match/exit/button" icon="icons/16px/home" icon_alignment="centre">
<layout class="centre_in_parent_attachment" alignment="vertical" offset="0" />
</widget>
<!--clock-->
<widget class="text" id="Mclk" size="12" width="80" alignment="centre" style="semi_bold" colour="match text">
<layout class="stick_to_sides_attachment" alignment="top" inset="1" />
</widget>
<widget class="text" id="Mijt" size="8" width="40" alignment="centre" colour="match scoreboard added time" style="semi_bold">
<layout class="stick_to_sides_attachment" alignment="top" inset="1" />
</widget>
...
<layout class="arrange_horizontal_attachment" alignment="horizontal" gap="0" offset="0" />
<layout class="fit_children_attachment" alignment="horizontal,fill" gap="0" offset="0" />
<layout class="stick_to_sides_attachment" alignment="vertical" layout_children="true" inset="0" />
<container width="10" />
<!--home button-->
<widget class="icon_button" id="homb" click_event="home" height="30" width="40" appearance="buttons/custom/match/exit/button" icon="icons/16px/home" icon_alignment="centre">
<layout class="centre_in_parent_attachment" alignment="vertical" offset="0" />
</widget>
<!--clock-->
<widget class="text" id="Mclk" size="12" width="80" alignment="centre" style="semi_bold" colour="match text">
<layout class="stick_to_sides_attachment" alignment="top" inset="1" />
</widget>
<widget class="text" id="Mijt" size="8" width="40" alignment="centre" colour="match scoreboard added time" style="semi_bold">
<layout class="stick_to_sides_attachment" alignment="top" inset="1" />
</widget>
...
The first line tells the game we want the following content nested inside a container with the settings of a bordered_box but with a custom appearance.
The layout elements then tell the game we want the nested items to display side-by-side with no gap, and we have several widgets to be displayed in a row, then as the other lines have set our horizontal placement we use the another layout element to set our vertical placement.
Next we have a blank container element; a width value is set to give us some padding from the left of the screen.
We then follow with some widget elements to display some items in game; we first display a home button and nest a layout element inside the widget element to centre it vertically.
Next we use some text widget elements to display the time and added time.
I haven't pasted in the rest of the code from that file, but if you look at the xml file you'll see the file contains similar code to create a new container nested inside the existing one to display the team name on top of the team background bar rather than alongside it like the rest of the content, this is because these widgets positions within the nested container are determined by the layout code within their container rather than the layout code within the parent container, the parent layout code only applies to the position of the nested container but not the code nested inside the container, thus by nesting the team name code within a new container you are able to display the name on top of the graphic when the previous code had items displaying side-by-side, then when you close the team name container we have another widget this time displaying the scoreboard which appears side-by-side again, we then finish with an away team container and an aggregate score widget before finally closing the initial container.
Other bits
If you are using Notepad++ to edit your xml files you'll notice that it gives different items different colours; tags and elements have a blue colour, attributes are red, attribute values are purple and comments are green. You can use this to give you a quick visual notification to make sure you haven't mistyped something. (Other programs may also colour the code but might use different colours).
Notepad++ can also try to help you by drawing grey vertical lines to try connecting open tags with the corresponding closing tag, though be aware this feature doesn't always link the correct ones. You may also have noted that various lines are indented differently with nested items having a further indent than their parent and linked open and close tags having the same indentation that can help keep track of which tags are linked.
You can also download a copy of this guide in several different formats for offline viewing:
---
Redistribution Terms
You are free to post this content to your website provided:
1. It is not sold or behind a paywall.
2. You don't advertise it as being exclusive to your website.
3. My username and blog address are included: http://michaeltmurrayuk.blogspot.co.uk/
If linking to the guide please link to this page rather than the direct download links as the links may change with updates.