Vous êtes sur la page 1sur 16

Modding Cities XL

Interface Principles
The game interfaces are created using Scaleform, which allows us to take Flash 8 files and use
the as game interface. However, in order to optimise performance, a lot of the flash is actually
loading image files, usually .dds files.

The interface is found in \Data\Interface

In this directory are :

\Bits
\Cfg
\DDSTexture
\Fonts
\Icons
\Panels
\Screens
\Video

Now, first the easiest folders and work our way up : Video and Fonts contain any videos and the
game fonts.

Screens describe the game screens : The intro, the main menu, the main game view, and so
on. These are described using LUA files. Usually these have OnOpen() and OnClose() functions
that are called when the screens are initialised.

A screen can show one or several Panels (which are stored in the Panels directory), these
Panels are usually started in the OnOpen function of the screen, using a call like this :

Interface:OpenPanel("SOMEPANELNAME")

Now, Panels have 2 files :
A gfx file, which is the export of the Flash file (and Actionscript) generated by the
scaleform exporter
A .lua file which is used as glue between the interface and the code.

So for instance in Data\Interface\Panels\Planet there is
Planet.gfx
Planet.lua

Now, here is the start of the S_PLANET.lua screen file :.

S_PLANET = {}

function S_PLANET:OnOpen()

InterfaceMgr.CurrentScreen ="PLANET"
PLANET:HideRessourceLayer()
Interface:OpenPanel("PLANET")
PLANET:OnPanelOpen()
PLANET:Init()


Interface:OpenPanel("PLANET")is what opens and shows the Planet.gfx file, and the
other PLANET:functionName() calls are functions in Planet.lua that are being called when the
S_PLANET screen is being opened.

For each of these Panel files, there is the possibility to define a function that will be called when
the game loop is called. This function is of the form PANELNAME:OnUpdate(). However for a
lot of these functions, there is simply a call to the main interface loop manager, called
InterfaceMgr, which manages the different processes going on in the interface. For instance, for
Planet.lua, the OnUpdate function is as follows :

function PLANET:OnUpdate()
InterfaceMgr:UpdateInPlanet()
end

Incidentally, that is also where the InterfaceMgr.CurrentScreen ="PLANET" comes
from, it is telling InterfaceMgr what state the game is in.

You wont find InterfaceMgr in the main Interface directory, it is in fact in the script directory
(Data\Design\Script) in the Interface sub-directory.

Panels can load up smaller files which are also Flash / Scaleform exports, these smaller
elements are called Bits and are in the Bits subdirectory of the main Interface directory.

These are usually called something like _Bits_PaneName.gfx

In general these are smaller panels that serve a specific purpose or are not the main screen
panel.

For instance, in the Planet.gfx panel, we load in :
_Bits_FindCities.gfx (the search cities pane)
_Bits_MapFilter.gfx (the map selection pane)
_Bits_MyCities.gfx (the list of my cities)

and so on.

Each of these (Panels & Bits) can load in dds files. These files are to be found in
Data\Interface\DDSTexture

The files are DDS files, either DXT1a or DXT5 format.

The button files are in
Data\Interface\DDSTexture\Buttons


Media Reports

Media reports are what we call the text appearing to the top in the center of the screen
showing the status of the city.

These reports are generated by a set of LUA files (in \Data\Design\Scripts\MediaReports)

Building description files (.class)

Al the buildings in the game as described using a xml type file with a .class extension.


Putting buildings in the game : The construction
menu, buildings, and tags
When starting up, the game parses all the .class files in the buildings directory
(Data\Design\Buildings) and adds them to the game, in the construction menu.

Where the buildings appear in the construction menu depends on how the building has been
tagged : the construction menu is in fact a search engine, where each button is a tag and the
buildings that appear are those that have the corresponding tags.

At the root of the game there is a Tags.cfg file (in XML type format), which is where the tags are
defined.

There are mainly 3 different types of tags :
Functional tags, that describe what kind of building this is in the game simulation (e.g.
Residence)
Size tags, which describe in which size category the building fits (T1, T2, T3, T3)
Wealth tags, mostly for residences and industries

Other tags you will encounter
MS18 - we used MSxx verionning tags to mark buildings that were compliant with the
latest version of the code, and this was the last version. Buildings must be tagged with
this to appear in the game
Deprecated - this is used to remove the building from the construction menu, without
having to delete the .class file which will corrupt any saved cities that contained this
building
GemCity - at one point we were working on other types of gameplay (Ski resort, beach
resort) but we never got round to finishing them. These other gameplays had specific
tags, and this tag is used to identifiy this building as not being part of these other side
gameplays.
PRIVATE used to identify buildings that are a part of the Citys budget, or not

If you open this file, you will see that some tags have children, and in the same way, the
construction menu has sub categories, for instance Factory is a child of Industry.

When adding a tag to a building with a tag, you will usually want to add all the parent tags too,
because the construction menu works by drilling down functional categories (so in this case the
menu allows you first to select Industry, and then Factory, so as both are selected in the
menu the building needs to have both tabs to be seen).

This rule is for functional tags (what the building does) and does not apply to wealth and size
tags.

A .class file in detail

Here is a sample file for a building in the game, you can find it in full in the annex. Ill walk you
through every section

View Section
<View>
<Panel>BuildingSelection</Panel>
<NameKey>&B_IND_NP02_T2</NameKey>
<NameKeySim>&B_IND_NP02_T2_SIM</NameKeySim>
<DescriptionKey>&B_IND_NP02_T2_DES</DescriptionKey>
<Param1Key>&B_IND_NP02_T2_PARAM1</Param1Key>
<Value1Key>&B_IND_NP02_T2_VALUE1</Value1Key>
<Param2Key>&B_IND_NP02_T2_PARAM2</Param2Key>
<Value2Key>&B_IND_NP02_T2_VALUE2</Value2Key>
<Param3Key>&B_IND_NP02_T2_PARAM3</Param3Key>
<Value3Key>&B_IND_NP02_T2_VALUE3</Value3Key>
</View>

This section determines how the building is shown in the interface
Panel : describes which pannel will be called to display the building information. Not sure
if this is plugged in or if the pannel is hardcoded.
Loc keys : The text that will be shown in the construction menu & selection panel, used
to set the building name, type description, and so on


Display Section
<Display>
<Model>Data/Gfx/Building/b_ind_np02new_t2.sgbin</Model>
<Placeholder>Data/Gfx/Placeholder/b_aaind_t2.sgbin</Placeholder>
<Fundament>
<Use>1</Use>
<Model>""</Model>
</Fundament>
<EditModeOnly>0</EditModeOnly>
<Thumb>""</Thumb>
<SelectionLayer>Array_PollutionAir</SelectionLayer>
</Display>

This section describes the 3d objects used to show the building in the game:
The main element is le Model node, which describes which sgbin (3d object) file is
used
Placeholder does not need to be changed, it is a fallback 3d model used in
developpment (when the final sgbin was not yet available)
Fundament :
Use: does the 3d model have a foundation : Most buildings have a square basis
and terraform the landscape, if the building doesnt need to terraform this can be
set to 0 (false)
Model : the model used for the foundation, usually doesnt need to be changed
Edit mode Only : Can this building be used in the game, or only in the editor (e.g. is it a
static decoration)
Thumb : Used to define the thumbnail that will be shown in the games construction
menu. If left empty, this will revert to a filename based on the model name (in this case,
b_ind_np02new_t2.dds)
SelectionLayer : This defines which simulation Layer is to be shown when the building is
selected. In this case, the Air Pollution Layer.

Placement Section

<Placement>
<Type>BUILDING</Type>
<GroundType>TERRAIN</GroundType>
<DelegatePrototype>""</DelegatePrototype>
<OverPickable>1</OverPickable>
<Merge>0</Merge>
<LinkPrototypeFile>""</LinkPrototypeFile>
<Terraform>
<Enabled>1</Enabled>
<UseDefault>1</UseDefault>
<DigDepth>0.3000000119</DigDepth>
<LevelWidth>15</LevelWidth>
<CutWidth>0</CutWidth>
<AngleMax>60</AngleMax>
<HeightMax>20</HeightMax>
</Terraform>
<DefaultHeightOffset>0</DefaultHeightOffset>
<LayerDisplay>LFRE_0</LayerDisplay>
</Placement>

The placement section defines how a building is to be placed :
The Type node determines which type of algorithm is to be called to do the placement.
BUILDING is the default mode, you wont need to change this in most cases. Roads &
surface buildings (like the garbage dump) use other placement types
Delegate Prototype, : this was used by surface buildings (like the garbage dump) to say:
when people ask to place me, use another prototype instead
Terraform/Enable : Does this placement mode support terraforming ?
LayerDisplay : Which Layer should be displayed when placing the building. In this case it
is the Freight ( LFRE_0) layer.


Layouts

The layout of a building determines where the different decorations (trees, cars, characters,
etc.) are placed within the building, and whether an offset in height needs to be applied to this
layout

<Layouts>
<UndefinedAdjustHeight>0</UndefinedAdjustHeight>
<LayoutFile1>Data/Design/Layout/B_Service/b_ind_np02_t2_Base.layout</LayoutFile1>
</Layouts>

EntityPosition

This is data used in the placement algorithm.
EntityPosition\CollisionShape\Dimension is the space the building occupies on the floor
(in meters)


<EntityPosition>
<CollisionShape>
<Dimension>40,40</Dimension>
<Height>20.12739944</Height>
<Use>1</Use>
</CollisionShape>
<UsePlugOrientationForSnap>1</UsePlugOrientationForSnap>
<AllowSnapAround>1</AllowSnapAround>
<GardenAsCarpet>0</GardenAsCarpet>
</EntityPosition>

Tags
<Tag>Industry;Factory;T2;MS18;GemCity;PRIVATE;Manufacturing</Tag>
Tags have already been described earlier in the document, they determine where the building
will appear in the construction menu.

Entity

This identifies the behavior components that are to be used by the building. In this case :
BUILDING : this is a basic company, i.e. not a residence and not a road. Use
RESIDENCE instead for residences.
SCZCOJOBPROVIDER : this building is a job provider, i.e. it employs citizens. This
component impacts others, i.e. if the building is unable to find employees, it will not
produce, or make money..
SCCORESOURCEAGENT : this building is a resource agent, it consumes and
produces resources
SLACOLAYER : this building impacts simulation layers (e.g. emits pollution, etc.)
These components have sections in the .class file that are associated with them.

<Entity>
<Type>BUILDING</Type>
<Serializable>0</Serializable>
<WithOptional1>SCZCOJOBPROVIDER</WithOptional1>
<WithOptional2>SCCORESOURCEAGENT</WithOptional2>
<WithOptional3>SLACOLAYER</WithOptional3>
</Entity>

Job Provider
Describes which type of Cultures (the term is inherited from City Life) the building employs
(LowLive, AllAm,Suit, Elite ), and how attractive these jobs are to citizens of these wealth
groups:

<JobProvider>
<MaxJobPerCulture>
<LowLife>1</LowLife>
<AllAm>2</AllAm>
<Suit>1</Suit>
</MaxJobPerCulture>
<JobAttractivityPerCulture>
<LowLife>10</LowLife>
<AllAm>10</AllAm>
<Suit>10</Suit>
</JobAttractivityPerCulture>
</JobProvider>

Resource Component
This section describes the resources the building consumes and produces :
In each node of the form MaxProduction\Production1 ..
ResourceName : the resource produced
ResourceNumber : the amount produced
ResourceUnitMinPriceBenef : the profits produced

In each node of the form MaxRequirement\Requirement1
ResourceName: The resource consumed
ResourceNumber : the amount of resource consumed

<ResourceComponent>
<MaxProduction>
<Production1>
<ResourceName>RIN2_0</ResourceName>
<ResourceNumber>300</ResourceNumber>
<ResourceUnitMinPriceBenef>17</ResourceUnitMinPriceBenef>
</Production1>
</MaxProduction>
<MaxRequirement>
<Requirement1>
<ResourceName>RELE_0</ResourceName>
<ResourceNumber>24</ResourceNumber>
</Requirement1>
<Requirement2>
<ResourceName>ROFF_0</ResourceName>
<ResourceNumber>60</ResourceNumber>
</Requirement2>
<Requirement3>
<ResourceName>RIN1_0</ResourceName>
<ResourceNumber>160</ResourceNumber>
</Requirement3>
</MaxRequirement>
</ResourceComponent>

Layer Component
The building had a layer component, which is how the buildings impact each other
geographically.There are various types of layers, and buildings impact Simulation Layers using
different Shapes.

Other layers include stuff like quality of life, noise, population density and so on. The interface to
the right side of the screen allows you to visualise on screen a certain number of these layers.

In our case, the layer is air pollution, and there are two impacts : one circular and one global to
the whole map.

<Layer>
<Shape01>
<LayerName>PollutionAir</LayerName>
<Radius>800</Radius>
<InfluenceMin>0</InfluenceMin>
<InfluenceMax>1</InfluenceMax>
<Type>CIRCLE</Type>
<DegressiveInfluence>1</DegressiveInfluence>
</Shape01>
<Shape02>
<LayerName>PollutionAir</LayerName>
<Radius>20000</Radius>
<InfluenceMin>0.01</InfluenceMin>
<InfluenceMax>0.01</InfluenceMax>
<Type>ALLMAP</Type>
<DegressiveInfluence>1</DegressiveInfluence>
</Shape02>
</Layer>

The Building (Budget Agent) component
This determines how the economy aspect of the building works : how much the building can
gain (MaxMonthlyBenefit) , how much it can loose (MaxMonthlyDeficit), its basic functionning
costs (UpkeepCost) and so on so on.

Of note is the fact that the building can be impacted by other layers, as described in the
Sensitivity node seen below.
IsPublicBuilding determines whether the buildings economy is directly imputed to the citys, or
whether it is only indirectly imputed via taxes.

<BudgetAgent>
<CitizenProvider>0</CitizenProvider>
<MaxMonthlyBenefit>2680</MaxMonthlyBenefit>
<MaxMonthlyDeficit>-7130</MaxMonthlyDeficit>
<UpkeepCost>3190</UpkeepCost>
<IsCityLink>no</IsCityLink>
<IsPublicBuilding>0</IsPublicBuilding>
<Sensitivity>
<Sensitivity01>
<Layer>LFRE_0</Layer>
<Percent>9</Percent>
<WarningPercentThreshold>1</WarningPercentThreshold>
</Sensitivity01>
</Sensitivity>
</BudgetAgent>

The conditions node

The conditions node determines under what conditions the building is visible and available in
the construction menu.

These conditions include the players ability to pay for the construction (ConstructionCost)

The VisibleConditions are the conditions which determine whether the building is visible in the
construction menu. In this case : MinNbBuildingOnMapWithTagsRelock1 : There needs to be
at least one building with the tags GemCity & TownHall before the building is visible. This is a
basic setting which most buildings have, so that players can start placing the town hall before
placing anything else (the economy is build in such a way that the town hall and all in one
buildings are required to kickstart the economy).

You can limit the number of buildings of a certain type on the map, by locking buildings if the
number of buildings with a certain tag configuration goes beyond a certain threshold.

The UnlockConditions are the conditions under which the building can be placed by the
player.
In our case, there also needs to be a town hall for the building to be unlocked, but there is also
an unlock condition on the number of citizens (NbCitizen). This number is the number of
simulation agents in the simulation, not the number of citizens visible in the interface.

<Conditions>
<ConditionSet1>
<ModeName>player_lock_all</ModeName>
<ConstructionCost>4000</ConstructionCost>
<DestructionCost>400</DestructionCost>
<VisibleConditions>
<MinNbBuildingOnMapWithTagsRelock1>
<Name>GemCity</Name>
<Name2>TownHall</Name2>
<Number>1</Number>
</MinNbBuildingOnMapWithTagsRelock1>
</VisibleConditions>
<UnlockConditions>
<NbCitizen>1075</NbCitizen>
<MinNbBuildingOnMapWithTagsRelock1>
<Name>GemCity</Name>
<Name2>TownHall</Name2>
<Number>1</Number>
</MinNbBuildingOnMapWithTagsRelock1>
</UnlockConditions>
</ConditionSet1>
<ConditionSet2>
<ModeName>player_lock_achievement</ModeName>
<ConstructionCost>4000</ConstructionCost>
<DestructionCost>400</DestructionCost>
</ConditionSet2>
</Conditions>








Resources List

Layers List


Full Class file

<?xml version="1.0" encoding="Windows-1252"?>
<!--Usine Moyenne T2-->
<View>
<Panel>BuildingSelection</Panel>
<NameKey>&B_IND_NP02_T2</NameKey>
<NameKeySim>&B_IND_NP02_T2_SIM</NameKeySim>
<DescriptionKey>&B_IND_NP02_T2_DES</DescriptionKey>
<Param1Key>&B_IND_NP02_T2_PARAM1</Param1Key>
<Value1Key>&B_IND_NP02_T2_VALUE1</Value1Key>
<Param2Key>&B_IND_NP02_T2_PARAM2</Param2Key>
<Value2Key>&B_IND_NP02_T2_VALUE2</Value2Key>
<Param3Key>&B_IND_NP02_T2_PARAM3</Param3Key>
<Value3Key>&B_IND_NP02_T2_VALUE3</Value3Key>
</View>
<Display>
<Model>Data/Gfx/Building/b_ind_np02new_t2.sgbin</Model>
<Placeholder>Data/Gfx/Placeholder/b_aaind_t2.sgbin</Placeholder>
<Fundament>
<Use>1</Use>
<Model>""</Model>
</Fundament>
<EditModeOnly>0</EditModeOnly>
<Thumb>""</Thumb>
<SelectionLayer>Array_PollutionAir</SelectionLayer>
</Display>
<Placement>
<Type>BUILDING</Type>
<GroundType>TERRAIN</GroundType>
<DelegatePrototype>""</DelegatePrototype>
<OverPickable>1</OverPickable>
<Merge>0</Merge>
<LinkPrototypeFile>""</LinkPrototypeFile>
<Terraform>
<Enabled>1</Enabled>
<UseDefault>1</UseDefault>
<DigDepth>0.3000000119</DigDepth>
<LevelWidth>15</LevelWidth>
<CutWidth>0</CutWidth>
<AngleMax>60</AngleMax>
<HeightMax>20</HeightMax>
</Terraform>
<DefaultHeightOffset>0</DefaultHeightOffset>
<LayerDisplay>LFRE_0</LayerDisplay>
</Placement>
<Layouts>
<UndefinedAdjustHeight>0</UndefinedAdjustHeight>

<LayoutFile1>Data/Design/Layout/B_Service/b_ind_np02_t2_Base.layout</LayoutFile1>
</Layouts>
<EntityPosition>
<CollisionShape>
<Dimension>40,40</Dimension>
<Height>20.12739944</Height>
<Use>1</Use>
</CollisionShape>
<UsePlugOrientationForSnap>1</UsePlugOrientationForSnap>
<AllowSnapAround>1</AllowSnapAround>
<GardenAsCarpet>0</GardenAsCarpet>
</EntityPosition>
<Tag>Industry;Factory;T2;MS18;GemCity;PRIVATE;Manufacturing</Tag>
<Entity>
<Type>BUILDING</Type>
<Serializable>0</Serializable>
<WithOptional1>SCZCOJOBPROVIDER</WithOptional1>
<WithOptional2>SCCORESOURCEAGENT</WithOptional2>
<WithOptional3>SLACOLAYER</WithOptional3>
</Entity>
<JobProvider>
<MaxJobPerCulture>
<LowLife>1</LowLife>
<AllAm>2</AllAm>
<Suit>1</Suit>
</MaxJobPerCulture>
<JobAttractivityPerCulture>
<LowLife>10</LowLife>
<AllAm>10</AllAm>
<Suit>10</Suit>
</JobAttractivityPerCulture>
</JobProvider>
<ResourceComponent>
<MaxProduction>
<Production1>
<ResourceName>RIN2_0</ResourceName>
<ResourceNumber>300</ResourceNumber>
<ResourceUnitMinPriceBenef>17</ResourceUnitMinPriceBenef>
</Production1>
</MaxProduction>
<MaxRequirement>
<Requirement1>
<ResourceName>RELE_0</ResourceName>
<ResourceNumber>24</ResourceNumber>
</Requirement1>
<Requirement2>
<ResourceName>ROFF_0</ResourceName>
<ResourceNumber>60</ResourceNumber>
</Requirement2>
<Requirement3>
<ResourceName>RIN1_0</ResourceName>
<ResourceNumber>160</ResourceNumber>
</Requirement3>
</MaxRequirement>
</ResourceComponent>
<Layer>
<Shape01>
<LayerName>PollutionAir</LayerName>
<Radius>800</Radius>
<InfluenceMin>0</InfluenceMin>
<InfluenceMax>1</InfluenceMax>
<Type>CIRCLE</Type>
<DegressiveInfluence>1</DegressiveInfluence>
</Shape01>
<Shape02>
<LayerName>PollutionAir</LayerName>
<Radius>20000</Radius>
<InfluenceMin>0.01</InfluenceMin>
<InfluenceMax>0.01</InfluenceMax>
<Type>ALLMAP</Type>
<DegressiveInfluence>1</DegressiveInfluence>
</Shape02>
</Layer>
<BudgetAgent>
<CitizenProvider>0</CitizenProvider>
<MaxMonthlyBenefit>2680</MaxMonthlyBenefit>
<MaxMonthlyDeficit>-7130</MaxMonthlyDeficit>
<UpkeepCost>3190</UpkeepCost>
<IsCityLink>no</IsCityLink>
<IsPublicBuilding>0</IsPublicBuilding>
<Sensitivity>
<Sensitivity01>
<Layer>LFRE_0</Layer>
<Percent>9</Percent>
<WarningPercentThreshold>1</WarningPercentThreshold>
</Sensitivity01>
</Sensitivity>
</BudgetAgent>
<Conditions>
<ConditionSet1>
<ModeName>player_lock_all</ModeName>
<ConstructionCost>4000</ConstructionCost>
<DestructionCost>400</DestructionCost>
<VisibleConditions>
<MinNbBuildingOnMapWithTagsRelock1>
<Name>GemCity</Name>
<Name2>TownHall</Name2>
<Number>1</Number>
</MinNbBuildingOnMapWithTagsRelock1>
</VisibleConditions>
<UnlockConditions>
<NbCitizen>1075</NbCitizen>
<MinNbBuildingOnMapWithTagsRelock1>
<Name>GemCity</Name>
<Name2>TownHall</Name2>
<Number>1</Number>
</MinNbBuildingOnMapWithTagsRelock1>
</UnlockConditions>
</ConditionSet1>
<ConditionSet2>
<ModeName>player_lock_achievement</ModeName>
<ConstructionCost>4000</ConstructionCost>
<DestructionCost>400</DestructionCost>
</ConditionSet2>
</Conditions>

Vous aimerez peut-être aussi