Art Development

## Getting Started

**1:100 SCALE** - ALL background art had to be modelled 1:100 in Maya (because Maya handled large values badly). An export scale was then used to scale the object back up – this will be explained later.

To work in Maya at 1:100, you simply had to set the working units to centimeters and treat 1cm as 1m (goto... window > settings/preferences > preferences > settings > working units > linear > centimeters).

It was useful to set the project folder in Maya to d:\user\work\<projectname> - that way all your Maya data is saved into the correct location. Using a different folder elsewhere would usually end up with pathing problems and you would need to re-path you textures each time you export something for the game.

**BACKFACE CULLING -** Backface culling was always turnt on in Maya (goto... view > backface culling) if a developer was viewing their work in a shaded view.

**NAMING FILES -** All game assets had to sit within the <projectname> folder under the appropriate sub-folders.

Anything that iwas not an in-game asset such as documents, concept art and reference would go into the <projectname>\_development (e.g.: d:\user\work\bf\_development\concept\_art) folder.

To stop accidental spelling mistakes developers had to always use abbreviations for long class names and categories.

For example; Battlefront has common classes/factions like Imperial/Empire, Confederacy of Independent Systems, Rebel and Republic.

These were standardized to IMP, CIS, REB and REP.

Levels names such as Kashyyyk, Mustafar, Coruscant were simplified to KAS, MUS and COR to stop simple spelling mistakes from happening.

Names always had to be consistent between setup files, build files, and art assets.
Directory names had to be the same as filename. Additionally, Maya file filenames had to be the same as the in-game .xml files.

For example...

bf / capitalships / cis\_command\_int / cis\_command\_int.mb
bf / capitalships / cis\_command\_int / cis\_command\_int.xml

**FOLDERS AND FILE STRUCTURE** - All background assets had to sit under <projectname>\backgrounds\

Each level had the abbreviated folder name like this:

<projectname>\backgrounds\kas

Within this folder there were the following folders:

BUILDINGS
FOLIAGE
PARTICLES
PROPS
SKYDOME
WORLD
TEXTURES

**Buildings** - The buildings folder contained all background structures both in XML and Maya format. Buildings are any object that is a static background element that has a lightmap.

**Foliage** - The foliage folder housed rocks and foliage files that were placed using the Terrain Editor.

**Props** – This folder contained all dynamic props such as destructable items and physics objects. Props were objects that did not have a lightmap.

**Skydome**  - This folder contained the level's main lighting XML and its textures. It also housed the level's skydome cubemaps that were created using HDRshop.

**World** – The world folder had two other folders within it; export and textures. The terrain folder itself contained the save data from the FRD World Editor. The export folder contained the ingame terrain files that were exproted from the World Editor.

**Textures** – All textures for the level buildings and props resided in this folder.

## Polygon and Texture Limits

Background w/out terrain - 90,000 polys

Detail Geometry - 15,000 polys

Foliage Spraying - 10,000 polys

Capital Ship Exterior Geometry - 10,000 + 15,000 polys

Vehicle Geometry (inc 3rd person cockpit) - 5,000 polys

Vehicle Geometry (1st person cockpit only) - 4,000 polys

Weapon Geometry (1st Person) - 4,000 polys

Weapon Geometry (3rd Person) - 500 polys

Destructible Prop Geometry - 4,000 polys

Character Geometry - 3,500 polys

Background w/ terrain - 150mb

Background w/out terrain - 180mb

Vehicle exterior - 10mb

Vehicle cockpit - 10mb

Capital Ship interior - 120mb

Capital Ship exterior - 30mb

Misc textures (Effects/Resident/UI textures) - 50Mb

Weapons - 10mb

Characters - 5mb

For surfaces the player can walk right up to textures should ideally be applied at **512 pixels across 1 metre.** This will be halved ingame to 256 pixels per metre.

Textures will be mipmapped, so if someone had multiple elements on one texture, they had to leave at least a 16pixel gap between them to prevent bleeding between elements. In most cases, a specular map was in greyscale, as this would save memory when the texture was compressed.

Developers didn't actually convert to greyscale mode in Photoshop, they just desaturated the image completely (CTRL+Shift+U). The only time they needed colour in their specular map was in cases where the material would tint the reflection (for example heat treated metals).

All textures were saved in **Targa (.tga)** format and saved as 24-bit. if there was no alpha channel, or 32-bit with an alpha channel.

## Creating a Prop

**BASIC PROPS:**

A prop is an object that is interactive with the player or gameplay. Props are usually dynamically lit and in most cases can be destroyed.

A prop can be any shape or size but it must sit on the origin i.e. The base of the prop should be at x0 y0 z0 and should face along the Z axis (front of the prop z+ back of the prop z-)

A prop can have up to three levels of detail (LOD's) and each LOD needs a physics rep/rigid body and should fit the object as close as possible.

Props should also have (if destructible) broken parts known as B\_GIBS that appear when the object has been blown up and a damaged state that remains in place after the explosion. A maximum of 6 gibs should be used on a prop, as more than this increases memory usage.

All of this data needs to sit under a group called BTOP and is be organized like this...

BTOP
exportscale

Also, you can see a group called exportscale sits outside of the BTOP. This groups X Y Z scale should be 100 and must exist in all scenes that are modelled 1:100 as described earlier.

Once a prop has been created, you had to make sure you saved and exported it to the props folder within the appropriate level folder...

D:\user\work\<projectname>\backgrounds\<levelname>\props\

If it is a generic prop (i.e. It will apear in various levels) then it was saved to the generic props location...

D:\user\work\<projectname>\props\

and a descriptive subfolder was created for these. For example... bf\props\misc\misc\_command\_post\

The placing of props was done by the designer using the Setup Editor. Props were not to be placed into a level via the World Editor – only background components were.

**ANIMATED PROPS:**

Animated props are set up in a similar way to basic prop.  However, the B\_ parts are replaced with bones instead of groups.

For example: A developer might have wanted to create a communications antenna that extends once activated. Here is how to set this up...

CHRTOP

As you can see, the base was going to be static, as it was just a normal group and the antenna had a bone instead of a group so that it could be animated.

**DOOR PROPS:**

Doors are useful for culling an entire room from the players view. These are particularly useful between interior and exterior sections.

If a developer was to make a door, they simply had to create the geometry to fit inside the door frame of their level and save it out as a prop. The door, when placed in the game, would sit half in one room and half into the other like this...

 File:Doors.png
This is so that there are no visible gaps around the portal line when the room is not drawn. For example, if the player is stood in room 1, he will see room 1 and the door but not room 2 until the door opens.

Doors could be all shapes and sizes but they were limited to translation and rotation.

Here is a typical door prop structure...

BTOP
exportscale

The origin (0, 0, 0,) of the door prop is the axis for rotation and translation. So, if the door needed to be rotated from a hinge then the origin must be at the point at which you would want the door to rotate around.

## Creating a Character

In-Game Characters: 3000-3500 polys, around 20-25 bones

Cutscene Characters: 4000 - 5000 polys, around 80 bones

2048x2048 (diff, norm, spec) used for the body, 1024x1024 (diff, norm, spec) shared between the face and arms.

## Creating a Weapon

**NOTE**: All weapons faced along the Z-axis (front of the gun is z+, back of the gun is z-).

1st Person: 3000-4000 polys

3rd Person: 3000-4000 polys

.mb and .xmls should have \_firstperson or \_thirdperson at end of filename to clarify which version they are.

e.g.     mp5k\_firstperson.xml
mp5k\_thirdperson.xml

The origin of firstperson weapons nneded to be at the wrist position, with a DOF\_CENTRE to show the centrepos.

The origin of thirdperson weapons was at the centre, with a DOF\_WRIST to show the wrist position (ie the other way around – unfortunately this was necessary).

Also, a DOF\_SHOOTPOS was also be placed at the centre of the barrel end but very slightly outside of the mesh – otherwise the bullet would just collide with the guns geometry.

Weapons were set up almost the same as animated props like this...

CHRTOP

## Creating a Vehicle

**NOTE**: All vehicles faced along the Z-axis (front of the vehicle is z+, back of the vehicle is z-).

**EXTERIORS -** 4000-5000 polys (including any 3rd person cockpit)
4096x4096 (diff, norm, spec)

Shoot positions were labelled with a DOF for both primary and secondary fire. For primary weapons DOF\_SHOOTPOS\_PRIMARY1, DOF\_SHOOTPOS\_PRIMARY2, etc. and for secondary weapons (e.g. rockets) DOF\_SHOOTPOS\_SECONDARY1, etc.

Each vehicle needed to have Physics Bounds (created using the Create Rigid Body tool in the FRD tool shelf) and also required B\_GIBS for when the ship was destroyed.

To add trail FX to ships you simply had to place a DOF\_TRAIL on each of the wing tips. Example: DOF\_TRAIL\_1, DOF\_TRAIL\_2, and so on.

DOF\_THRUSTER also had to be placed on each thruster on the mesh.

Each space going vehicle required a re-entry effect shield. This was defined by creating a simple mesh around the ship model and labelling it B\_shield.

Vehicle LODs needed to be saved as separate Maya and XML files, but had to be identical in structure. In other words they needed to have the same amount of parts and dofs etc. (please note: No new/extra textures were to be used on the LODs)

Each LOD file needed to be saved next to the main “high” poly model. For example...

bf/vehicles/reb/reb\_xwing/reb\_xwing.mb
bf/vehicles/reb/reb\_xwing/reb\_xwing.xml

bf/vehicles/reb/reb\_xwing/reb\_xwing\_med.mb
bf/vehicles/reb/reb\_xwing/reb\_xwing\_med.xml

bf/vehicles/reb/reb\_xwing/reb\_xwing\_low.mb
bf/vehicles/reb/reb\_xwing/reb\_xwing\_low.xml

**INTERIORS -** up to 4000 polys (including any exterior)
2048x2048(diff, norm, spec)

The cockpit position was similar to the cockpit in the exterior version - however, it did not have to match the actual exterior geometry. A DOF\_CAMERA was placed for the camera position.

Visibility was VERY important in cockpit mode. The cockpit had to not obscure the centre of the screen and could take up no more than 25% of the screen, even if realism were to suffer. (note: the character arms would not be drawn)

Developers saved out the cockpit file alongside the main files like this...

bf/vehicles/reb/reb\_xwing/reb\_xwing\_cockpit.mb
bf/vehicles/reb/reb\_xwing/reb\_xwing\_cockpit.xml

## Creating a Background Component

A background component is an object that was loaded into the World Editor and formed the static background/level geometry.

All geometry for a background component had to sit inside a room node (RO\_) otherwise it would not be exported and would not appear in-game.

This is a typical background component setup...

RO\_default

RO\_small\_building\_int

RO\_underground\_cave
exportscale

In the game there was a default room (RO\_default) that was there all the time. In other words, the RO\_default represented the game world/space and was drawn all the time. Objects inside RO\_default absolutely had to make good use of LODs and occluders as this was be the primary way of reducing the number of polys being drawn in worldspace.

**NOTE**: For the purpose of keeping a scene as tidy as possible. it was a good practice to place technical elements in a group called TECH. It was recommended for developers to have a TECH group within each top node i.e. BTOP or RO\_ and inside these groups should be things like PORTALS and DOFs etc.

## Portals

Rooms were joined together with portals – these portals are polys (quads) that were placed at a doorway into another room. Portals had to be planar along the y-axis. Horizontal portals could be used in some situations when the player could not pass through them.

A portal had to sit in one room and point to another room. To do this you simply had to create a poly that fit the doorway area and rested on the room's border or edge.

Note: Room 1's geometry must not overlap into Room 2 otherwise a flickering/disappearing room effect will happen and may cause other problems.

File:Portals.png
As you can see from the following image the portal geometry (PO\_02) is a child of RO\_01 and because the portal is called PO\_02 the engine knows to link room 01 to room 02.

Developers had to always try to make room names descriptive as it would be less confusing when you would have lots of rooms to deal with. (i.e. RO\_entrance\_hall or RO\_landing\_bay etc.)

## Fade Portals

A fade portal could be used to turn off a room at a distance. Fade portals did not actually fade out but rather instantly turned off at a set distance. To set up a fade portal you simply created and applied a beam shader onto the portal.

File:Beamfade.png
As you can see here, this setup would turn off the portal when you were 100m away from it. To increase or decrease the distance you simply had to change the distance start setting. All other values were 0.

To archive the fade effect you would need to create an extra poly that sits in the same place as the portal but this time apply a texture that represents the adjacent room. Then apply a beam shader to it with the same settings.

## LODs

In Maya, you would need to create the different LOD states of the geometry and name them B\_<name>\_high, B\_<name>\_med and B\_<name>\_low.

Afterwards, you would need to group these separate objects under a group called LOD\_<name>, where <name> is the same as the name in the individual objects. Then, you would have to place all the LOD\_<name> group inside a  group called LIGHTMAPPED (if using lightmaps!) or GEOM (if it is a prop) and then place that group under the BTOP.

You had to have at least two states in a LOD - otherwise you could not label it as LOD\_ .If you required just two states, you could use the B\_<name>\_high and B\_<name>\_low.

The LOD distances could then be set up on a component or all the components within the World Editor.

## Occluders

Occluders were simplified 3D meshes that represented the volume of an object/background component. What happened was that when a character, prop, room or vehicle went completely behind the occluder, it was switched off and not drawn. This reduced the amount of polys visible from the player's perspective.

Occluders were highly effective in outdoor areas that were extremely hard to portal efficiently such as... well, pretty much all Battlefront levels.

Occluders had an associated 'cost' in CPU time just like Portals. Simply put; the more occluders on-screen = more CPU time.

## Simple Collisions

Every background component had a separate simplified collision mesh. This mesh represented the actual geometry the player, vehicles and A.I. walked on and collided with.

Small details such as pipes were represented as simple bounding boxes and stairs or small steps would become ramps.

All this simple geometry would then sit inside a group called COLLISION\_<desciptive\_name>.

Hit decals and bullets, first test against the simple geometry and then actually test against the background geometry to decide if it has hit or not. So if you were to have a wooden fence made from a number of posts and cross beams you could represent this as a simple bounding box as the hit would still test against the background.

## Decals

Decals could be used to break up surfaces, add detail and/or add lighting FX to areas where the lightmap resolution was poor. But, developers had to use them carefully as huge polys with alpha would increase the fill rate and impact the performance of the game.

Also, it was recommended to use additive and multiplicative for light and shadow effects because alpha textures did not compress down as much as a texture without alpha.

Decals could be flat against other polys as long as a developer set the layer attributes in the FRD Shader Tool. To do this, you had to create a shader and load the textures you want, then scroll down to the 'extra values' section and in the ID field type 'layer' and in the 'value' field type '1'.

This would force the shader of the decal to draw on top of the poly behind stopping any z fighting.
If you wanted another decal to draw over the top of the previous shaders, you simply had to follow those steps again and increase the 'value' to 2 and so on.

In most cases decals would not want to cast shadows or have a lightmap applied to them. Grouping decal geometry into its own group meant that you could select all of them and set the 'cast shadows =  off' attribute using the attribute spreadsheet.

If you were to do this, you would need select all the geometry within the decals group (don't select the group itself) and then open up the attribute speadsheet (window > general editors > attribute spreadsheet) and select the render tab. On this sheet you should have been able to see a column called 'cast shadows'. Select the entire column and type 'off' then press enter.

## Lightmap UVs

Background components could be lightmapped using the in-house renderer Bacon.

However to do this your model needed to go through the following process...

* Group together all your geometry that needs a lightmap into the group LIGHTMAPPED. This group should not include portals, DOFs, lightglows or beam shaders but must contain all geometry that you intend to have pre-baked lighting.
* Click on the “light map” FRD tool on the FRD shelf and enter in the pixels per meter required for your component.
	+ **NOTE**: Developers were working to 4 pixels per metre and because they are working at 1:100 scale, the value in the FRD lightmapping tool was set to 400.
* If this is the first time you have set up lightmap UVs on a component simply click “Auto Layout Lightmap UV's” otherwise click on “delete all lightmap data” if you have modified the geometry of an already lightmapped component.

## Lights

Background components - especially interiors needed lights added to them. There were two ways of doing this.

* Add lights into your Maya files – create a LIGHTS group inside your RO\_ group and create lights into the desired position. The problem with this method is that you are working blind because there is no way of getting realistic feedback of what the lighting will look like once rendered in Bacon.
* Add lights using the World Editor – this method is better because the coders have control of getting the lights to match/simulate the intensity and falloff of the bacon lights.

The lighting information from these lights will be baked onto a lightmap texture.

## Light Glows

A light glow was a single four sided mesh with an additive texture applied to it. Light glows could be used to add extra visual FX to background geometry interned to be a light source.

For example, you might have a light bulb in a room or a car head light that would look really cool if the light source had some sort of star filter effect of it.

If you were to create a light glow, you would simply have to create a quad/plane and apply your desired texture to it. This works best if you create an additive shader and use a texture like this...

 File:Lightglow.png
Then group the geometry and call the group node GLOW\_<descriptive\_name> and place it into a group called LIGHTGLOWS with each of the RO\_ groups.

Next, you would need select the GLOW\_ and use the FRD tool “Attribute Editor” and click “Add attributes to selected” The attributes that could then be added to a glow are...

* Distance Fade: Fade out with distance.

* Distance Scale: Scale with distance.

* Blend Mode: Choose from `Add` or `Multiply` to change the way the glow is rendered.

## Creating a Capital Ship

**EXTERIORS** - The budget for capital ship exteriors was 10,000 polygons. An additional 15,000 could be added and flagged as detail, which would only be turned on when close to the ship.

3 sets of 4096x4096 maps can be used for the exterior. The center of capital ship exteriors was the origin.

**INTERIORS** - Around 6 texture sets were used for the interiors of capital ships and creation of the interiors are pretty much the same as background components.

One additional feature of capital ships is the TRANSFORMATION PORTAL. These portals allowed the interior of the capital ship to be in a completely different location to the exterior but by magic make them look and work like they are in the same place in the world.

**CAPITAL SHIP LODs** - Capital Ship LODs needed to be saved as separate Maya and XML files but also had to be identical in structure. In other words, they needed to have the same amount of parts and DOFs etc. (please note: no new/extra textures were to be used on the LODs)

Each LOD file needed to be saved next to the main “high” poly model. For example...

bf/capital\_ships/cis/cis\_cruiser\_exterior/cis\_cruiser\_exterior.mb
bf/capital\_ships/cis/cis\_cruiser\_exterior/cis\_cruiser\_exterior.xml

bf/capital\_ships/cis/cis\_cruiser\_exterior/cis\_cruiser\_exterior\_med.mb
bf/capital\_ships/cis/cis\_cruiser\_exterior/cis\_cruiser\_exterior\_med.xml

bf/capital\_ships/cis/cis\_cruiser\_exterior/cis\_cruiser\_exterior\_low.mb
bf/capital\_ships/cis/cis\_cruiser\_exterior/cis\_cruiser\_exterior\_low.xml

## Creating a Walking Vehicle

Walking vehicles needed to be set up as follows:

* Each section of an articulated leg should be under it's own B\_ folder. For example, B\_LEFTSHIN, B\_LEFTANKLE etc.
* DOFs should be placed at each joint, with a sensible name for each one. For example, DOF\_LEFTANKLE TOP, DOF LEFTANKLEBOT etc.
* If your vehicle also has an animated head, the DOF for the joint between the head and the neck should be called NECKTOP.
* The vehicle should be in a default standing pose. File:Outliner.png

Developers had to make sure the folders containing the geometry were named to describe the position of that joint, and the geometry is named using that convention too. i.e - B\_RKNEE (containing) R\_KNEE (containing) DOF\_RKNEETOP and DOF\_RKNEEBOTTOM.

When placing DOF locators only one per position ws required. For instance - rthigh and rhip required only one DOF and could be placed under either part as long as it correctly described where you would like the rotation of that part to begin.

## Creating a Turret Prop

**NOTE**: The centre of a turret was at the origin and face/point along the Z-axis.

Exteriors - 2000-4000 polys / 4096x4096 (diff, norm, spec)

BTOP
exportscale

Each turret required physics bounds (created using the Create Rigid Body tool in the FRD tool shelf) and also required B\_GIBS and a damaged state B\_DAMAGED for when the turret is destroyed.

For the animation of your turret you would need to specify where the pivots between the parts would be. To do this, DOFs were placed at each joint, and their axial rotation specified within the name.  E.g. DOF\_Y\_AXIS for the turret and DOF\_X\_AXIS for the gun.

#### **Creating Turret LODs**

Turret LODs needed to be saved as separate Maya and XML files but they also had to be identical in structure. In other words, they needed to have the same amount of parts and DOFs etc. (please note: no new/extra textures were to be used on the LODs)

Each LOD file needed to be saved next to the main “high” poly model. For example...

bf\props\turrets\reb\reb\_turret\_vehicle.mb
bf\props\turrets\reb\reb\_turret\_vehicle.xml

bf\props\turrets\reb\reb\_turret\_vehicle\_med.mb
bf\props\turrets\reb\reb\_turret\_vehicle\_med.xml

bf\props\turrets\reb\reb\_turret\_vehicle\_low.mb
bf\props\turrets\reb\reb\_turret\_vehicle\_low.xml

## Skies, Atmospheres and Scene Lighting

A background may require a skydome folder that contains all the data needed to create consistent lighting, atmosphere and sky colour.

A level required 3 elements to give consistent lighting and atmosphere.

1x Cubemap for the atmospherem 1x cubemap for the space skybox and 1x image based lighting texture (that was used to light the level).

For example: bf\backgrounds\tat\skydome

tat\_ground\_sky.tga – this texture is a cubemap and loaded into the atmosphere shader. This texture represents a 360 degree image of the atmosphere colour. As the player moves up into space you essentially leave the atmosphere behind you like a sort of volumetric layer above the planet surface.

tat\_space\_sky.tga – this texture is also a cube map and represents a 630 degree view of outer space. As you move out of the atmosphere you see more and more of this texture.
Typically this texture would have stars, nebulas, and possibly some small planets and/or moons.

tat\_ground\_ibl.tga – this texture is a variation of the tat\_ground\_sky.tga texture (but not necessarily the same!) and used as a light (a Mental Ray IBL node) to light the level so that it matches the atmosphere.

tat\_ground\_ibl.xml – This is a scene setup using Maya that contains the main planet lights such as sunlight and IBL node (tat\_ground\_ibl.tga as described above). This XML is then used to light the whole world/level.

## Creating a World

**TERRAIN** - Clicking on new bg would create a new terrain world. If you did not want a terrain level, you could simply run the World Editor and start importing components.

**FOLIAGE -** These objects were saved into the foliage folder within the level's background folder. For example: bf\backgrounds\tat\foliage.

Foliage could be anything from a flat poly (quad) to a very low poly mesh. Foliage did not need to be just grass and plants, it could be other small details such as rocks, sticks and rubble and even litter.

More information regarding Terrain and Foliage here.

## Milestone Art Cut-off

The art cut-off for a milestone happened roughly two weeks before the milestone build is sent.
This ensured that all art was submitted so it could be checked/implemented by the code and design departments in time for their cut-off point which is one week before the milestone deadline.

The following week was when the build got tested by QA to ensure that FRD delivered a stable build of the game.

After the art cut-off NO artwork could be submitted to Perforce unless a developer was instructed by a lead or if they were working on a task/problem that was directly related to the milestone build.

## Notes on using Perforce

No Maya Swatches. This happened when someone would submit a textures folder rather than selecting the files within the folder. If a developer happened to upload swatches they had to ask [name redacted] to delete them or instruct them on how to remove them safely.

No “test” stuff unless it has been requested by a lead or coder. Where possible, all test items had to sit within bf\backgrounds\test\_levels\<name\_of\_test\_folder>.

No  workspace.mel – again like the swatches this could be accidentally uploaded by submitting the folder rather than the files.

No manual revisions of files – there is no need to submit increments like “my\_file\_01.xml” ,“my\_file\_02.xml” ,“my\_file\_03.xml” and so on. Perforce handled version control,  that is what it was used for. A developer's files had to be saved as “my\_file.xml”.

No textures along with Maya and XML files – developers had to stick to the file structure previously mentioned.

## Important Notes

Developers ALWAYS had to make sure whatever they submitted to Perforce would build. They always had to check that their textures were pathed correctly and were submitted to Perforce. They had to ensure they had an export scale node present and that they grouped everything under a BTOP (for props) or RO (for background rooms).

If the asset already existed in a build file (i.e. a designer placed a developer's file into a level) they always used the G6 asset remake web interface to make sure that it would build without errors, before asking the setup person to remake the asset.