Jump to content
Sign in to follow this  
You need to play a total of 5 battles to post in this section.
MatroseFuchs

Unbound How-To

1 comment in this topic

Recommended Posts

Administrator
29 posts
22 battles

Let’s have a look at mod creation on Unbound and take a mod showing the win rate in the ship carousel as an example.

To create a mod, we need to get three main tasks completed:

  1. Get necessary data;
  2. Process the data correctly;
  3. Display the result.

The statistics can be viewed in the game client in the Port in the Profile  Summary:

Spoiler

winRate_base.png

Please note that the win rate is shown for a specific battle type, take this into account when processing the data.

Let’s find out how to get the data.

To work with game client files, you need to extract them with the help of a utility. We unpack the directory res\gui\unbound to create our mod. The files will be extracted to “..\World_of_Warships\res_unpack\gui\unbound”. In the extracted files, we need to find files working with win rate statistics. Let’s search all the files by the word “victory” as the closes one in terms of meaning and have a look at the result:

Spoiler

search_victory.png

The search results will contain the file dock.xml (this is our port) and the closest match. As our profile is in the port, it is logical to start searching this file. We open dock.xml and look at the matching area. We will find the winRate attribute in the line above:

Spoiler

find_winRate.png

Looks like this is what we want. We can see that this parameter is in the statData field; now let’s see where it is.  We go up and discover that statData initializes in the main block <block className="PlayerSummary">,

Spoiler

statData.png

It is also a property of dataComponent located in statDataEntity.

Let’s look at the content of statData. Unfortunately, you cannot use debugging tools when working with XML files, therefore we create a simple text block to display the content. We add the style class, so that the text color is white and not black by default:

Spoiler

statData_debug_code.png

As some parameters can contain not only string and numerical values but also information in the object format, we use the method reflect() similar to the function rtrace() in AS3 to have the desired parameter displayed correctly. As this block displays black text I recommend adding the textDefault class to the block to make the text white and outlined in order to simplify tracing.

 

Please note!

To have changes made to the XML file displayed in the game client, you need to assemble an SWF file https://forum.worldofwarships.ru/topic/51786-правка-unbound-xml/, put it in “World_of_Warships\res_mods\<game_version>\gui\flash”, put USSExpressionsLoader.xml next to it with the path to the SWF file added to it, put the updated XML file in “World_of_Warships\res_mods\<game_version>\gui\unbound” and start the game. We assemble the SWF file again after every change.

When we go to Profile → Summary (remember that statistics are displayed in the Summary in the player profile) we see statData content displayed there:

Spoiler

statData_profile.png

If we change the type of battle to have statistics displayed in the profile, we will see changes in statData as well: now data are displayed for the selected battle type.

In the obtained data, we find shipsList consisting of dictionaries with fields for every ship, including winRate. We can also see in dock.xml that shipsList is also contained in dataComponent and is declared in a separate variable.

Spoiler

trace_info_xml.png

We can consider the first task done. We now know that the win rate for very ship is contained in shipsList in dataComponent.

Now let’s see how to get the same data for the ship carousel.

First of all, we need to display statistics by a certain battle type selected next to the Battle! button. Let’s find this parameter in the code. As you can see below, the battleType variable is responsible for the type of battle:

Spoiler

battleType_code.png

We can suppose that this variable or something similar to it should also be located in the block close to the Battle! button element. Let’s try to find this button element and search for something related to “button” and “battle”. We will find the following elements: StartBattleButtonBig and StartBattleButtonSmall, as well as BattleTypeChooser below:

Spoiler

BattleButonBig.png

Spoiler

BattleButonSmall.png

Spoiler

BattleTypeChooser.png

Looks like it’s what we need. We study these elements and see the following:

Spoiler

selectedBattle_code.png

There is a variable selectedBattle containing the selected battle type selectedBattle.type. Now we know how to get access to the selected battle type.

Now let’s find out how to get shipsList for the selected battle type. We already know that dataComponent is contained in statDataEntity. Let’s see what we can use there:

Spoiler

statDataEntity.png

While searching for shipsList we could notice that the entity statDataEntity is an element of the collection statDataEntities. When we have a closer look at this collection we’ll see that it consists of one element and contains such components as dataComponent and rankedSeasonHistory. If you take an entity with a different component also containing the dataComponent component and look into it, you will see that dataComponent of this entity contains information related to the selected component. You can see that the component rankedSeasonHistory contains the field gameType responsible for the battle type.  So, if we set the selected battle type for this component we can get shipsList with the necessary win rate from dataComponent. Let’s check out our hypothesis.

Note that you use a dot when accessing the object field (“object.field”) as it is its property in AS3.

In the code below, you can see a binding giving us an entity with a component filtered by the required field:

Spoiler

rankedSeasonHistory_filter.png

Let’s use it. Now let’s get the selected battle type value. Let’s take the entity containing the component rankedSeasonHistory with the selected battle type, and get shipsList from dataComponent (that our entity will have, as we already know) and display it on the screen:

Spoiler

trace_info.png

So, we see the list of ships filtered by battle type with fields showing their win rate (the string representation is winRate, the numerical representation is winRateNum). Let’s select another battle type and notice that shipsList now has data on ships we played in this type of battle. So, we can say that the second task has also been completed.   

Now let’s get down to visualizing the result. First, we need to find the element where we will display our win rate. We are looking for a ship carousel and a ship slot in it. Searching for a carousel in all XML files will return a lot of matches, but on closer inspection you will find our dock.xml.

If we search a bit using a simple text block with the value “Hello World!” as a debugging instrument (see documentation, the Blocks section) we will find the main carousel element CarouselItem:

Spoiler

CarouselItem.png

CarouselItem_dock.png

Here we can process our ship list and get the win rate for every ship. First, let’s get the list filtered by the battle type:

Spoiler

CarouselItem_shipsList_byType.png

When working with the list we use the binding indexOf allowing us to get a list item for the current ship slot. It’s obvious that a separate ship with various properties will be defined for every carousel slot, and a ship ID will probably be among them as well. When scrolling down we will see that it is so:

Spoiler

CarouselItem_shipId.png

With the help of the binding indexOf we will get a list item index for the current ship slot and take the value winRate. Let’s have a look at the result:

Spoiler

CarouselItem_shipWinRate.png

Doc_carousel_winRate.png

As you see we have the win rate displayed for every ship depending on the selected battle type. In our next step, let’s find the slot element, both big and small, to place the win rate inside the slot. The search will result in finding ShipCarouselDefaultSlot – a slot of the regular size,

Spoiler

DefaultSlot_code.png

DefaultSlot_port.png

and below there will be the small slot ShipCarouselSmallSlot. Let’s find out how data is passed to a slot, for example, the ship tier and bindings used for that.  In the slot element, let’s find a block responsible for placing the ship tier value:

Spoiler

block_shipLevel.png

Here we can also see what text style is used, as well as the way of positioning the block inside the element. Now let’s see how this parameter is passed to the slot element:

Spoiler

slotWrapper.png

levelRome.png

Let’s pass our win rate the same way:

Spoiler

slotWrapper_addWinRate.png

Then we add a block displaying values with the same top and bottom margins and text style similar to the ship tier so that all slot elements match visually:

Spoiler

block_winRate.png

dock_winRate.png

Let’s add finishing touches now, namely, color gradation of the win rate similar to the tank mod and set the following condition: if there is no win rate the text block remains empty. To do it, we take a numerical representation of the win rate and the binding <bind name="style" value="'textColor'; …”> to change the text color:

Spoiler

final_block_winRate.png

final_dock_winRate.png

Let’s repeat the block for a small slot:

Spoiler

smallSlot_winRate.png

As a result, we get the mod displaying the ship’s win rate for a selected battle type in a small and ordinary carousel.

 

PS.

Don’t forget to reassemble the SWF file after every change to the XML document and replace files in corresponding folders in res_mods.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

×