Welcome to Cafu Engine’s documentation!¶
Quick Start¶
The User Documentation describes the Cafu Engine Demo packages that are released periodically to demonstrate the features of the Cafu Engine.
This section is intended for advanced users who are experienced with downloading and installing software. If you are in a hurry and don’t want to study the entire document, but still want to make sure that you don’t miss any of the important Cafu features, you will find everything here to get you started:
- Installation is reduced to unzipping the downloaded file.
- Double-clicking on
Cafu.exe
starts the program. - In the program main menu click on New Game, then select a map in the following screen and click Go! to start the game.
- The
ESC
key opens the main menu again, where you can change game options or quit the game. TheF1
key opens the in-game console. - If you have questions, please consult the rest of this documentation first. If you can’t find your answer here, please join and post a message at the Cafu forums – we’re happy to help!
Installation¶
Minimum System Requirements¶
Cafu has been designed to run on a very broad range of hardware. Therefore, meeting or failing a certain set of minimum system requirements is not necessarily a question of getting all-or-nothing. Instead, the details of a systems hardware usually just scale the performance and/or the quality that the Cafu engine can achieve on that particular system – it even has automatic fall-back capabilities built-in in order to handle old and very old hardware well.
Your computer system should meet the following minimum requirements for Cafu to run (failing these requirements probably means that Cafu does not run at all):
- Intel i386 compatible CPU with 2 GHz
- 1 GB RAM (2 GB with Windows Vista or 7)
- 3D graphics board with OpenGL support and 256 MB graphics RAM
- Windows (2000, XP, Vista, or 7) or Linux operating system
- TCP/IP (network drivers)
- On Windows: DirectX 7.0 or higher
Systems that do not meet these requirements may still work fine with Cafu, but both the main processor and/or the graphics processor RAM may easily be exceeded by loading larger maps with many textures, resulting in very bad performance. You can use the Cafu Options dialog then to reduce the texture quality and/or load smaller maps.
In addition to the above, here is a list of recommended system features that allow Cafu to run reasonably well (in all cases, more is better):
- Intel i386 compatible CPU with 3 GHz
- 2 GB CPU RAM
- contemporary 3D graphics board with OpenGL support, programmable GPU and 256 MB graphics (GPU) RAM
In order to use the advanced networking features of Cafu, the network environment of your system must be appropriately configured.
In other words, if some of the modern commercial 3D computer games run on your system, then this is a good indication that Cafu will work, too.
We are developing Cafu under Windows and Ubuntu Linux, and test it on as many platforms as we can get access to. We have only little experience with other Linux distributions, but have received only positive reports up to now, regarding compatibility with all supported operating systems.
Installing Cafu¶
In order to install Cafu, simply unzip the packed file that you
downloaded from the website. Please make sure that the directory
structure is preserved. This is the common extraction process for nearly
all contemporary decompression software. However, for some older
programs you need to explicitly specify a command line option or check a
checkbox. A new directory like Cafu-9.06
will be created and all
files will be extracted into this directory.
Upgrading¶
In order to upgrade the engine from an older, existing installation, please delete all the old files and directories and then re-install the new version as stated above. We are sorry for any inconvenience caused by this, but this is the best way to avoid many possible upgrade and version conflict problems.
De-Installation¶
Because the installation makes no changes to your system, it is
sufficient to just delete the Cafu-x.y
folder for a completely clean
de-installation.
Running Cafu¶
In order to start Cafu, simply double-click on the Cafu.exe
executable file. This file is in the Cafu-x.y
folder that was
created during installation.
Keyboard Layout¶
In order to control the player and operate the game, you can use the keys as shown in the table below. The demonstrated layout reflects both keyboard-only player control layout and the popular mouse+keyboard player control layout. The keyboard layout will be made user configurable in future releases.
Action | Key | Alternative |
---|---|---|
Move forward | (Arrow up) | W |
Move back | (Arrow down) | S |
Turn left | ← (Arrow left) | (Mouse left) |
Turn right | → (Arrow right) | (Mouse right) |
Strafe left | A |
, |
Strafe right | D |
. |
Jump | SPACE |
|
Walk | R_SHIFT |
L_SHIFT |
Run (even faster) | R_CTRL |
|
Look up | PAGE UP |
(Mouse up) |
Look down | PAGE DOWN |
(Mouse down) |
Look banked CW | HOME |
|
Look banked CCW | INSERT |
|
Look straight ahead | END |
|
Talk / Chat | T |
|
Toggle Console | F1 |
|
Screen-shot | F5 |
|
Quit program | ESC |
Keyboard layout for player control and game operations.
The Command Console¶
In order to activate or deactivate the in-game console, press the F1
key.
The large upper area of the window shows the console output of any
component or subsystem of Cafu. The “Close” button in the lower right
corner closes the console window again, bringing you back to the game.
Other options to close the console window include pressing the F1
or
ESC
key. The “Clear” button clears the contents of the console
output window.
The text input field in the lower left is used for entering console
commands. Note that the TAB
key command-completion feature is
available to facilitate text entry. The up and down arrow keys navigate
through the command history for repeating previously entered commands.
Technically, the console interpreter is actually an instance of a Lua program in interactive mode. The Cafu engine binds its console variables and functions to that program so that they can be accessed like any other native Lua value. You may want to refer to the Lua documentation to learn more about the language Lua and its possibilities. The fact that you can write entire Lua programs at the Cafu in-game console provides great customizability and flexibility for both game developers and users.
Nonetheless, the Cafu console can also be used without any prior Lua knowledge, or any programming knowledge at all. Here are some getting-started examples that demonstrate the basic usage:
Entering the command
help()
prints out a short help text with instructions on how to obtain more
help and the list of all available commands. Note that help()
is
actually a function call and therefore the brackets are mandatory.
list()
lists all available Cafu console functions, console variables, and
global Lua values. As such, the list()
function is useful to look-up
the available commands. Note that the TAB
key for command-completion
serves a similar purpose, but the list()
function provides more
information about the values and the output is formatted.
help("quit")
list("cl")
The help(“quit”)
function call provides help specific for the
quit
console variable, including a description of its purpose. This
works analogously with any other console command, too. The
list(“cl”)
call works like the normal list()
, but restricts the
output to values that begin with the string “cl”
.
screenSuffix="png"
sets the value of the console variable screenSuffix
to png
. Use
this when you want to save your screenshots in png
image file format
instead of the default jpg
. Enter help(“screenSuffix”)
for more
information about the screenSuffix
console variable.
rcon("changeLevel('filename')")
rcon
is the abbreviation for “remote console”. It means that the
rest of the line is not processed by the local client, but rather sent
to the remote server console. Therefore, this line instructs the server
to initiate a level (world) change.
Pressing the F1
key deactivates the console and brings you back to
the game.
The config.lua File¶
When Cafu.exe
starts up, it automatically processes the
config.lua
file. The config.lua
file is located in the Cafu base
directory. It is run in the context of the in-game console and can
therefore contain any statement that you could also enter interactively
as described above. Because the config.lua
file is processed early
during engine initialization, it is the ideal place to set default
values and to keep any console statements that you find yourself
entering over and over again. You can also define new functions or
convenient abbreviations, and in fact, a complete, full-featured Lua
program can be written into this file, either by the user, the game
developer, or both. Just have a look into the config.lua
file in the
Cafu base directory to see some examples.
User FAQ¶
Why does my Personal Firewall report Cafu.exe?¶
When you start Cafu, it internally starts a client and a server, then
connects to itself when a new map is loaded. This is done even for pure
single-player games, and thus your Windows or Personal Firewall reports
that Cafu.exe
is establishing a network connection.
Therefore, please set your firewall to not block Cafu from network
access. If you do not plan to host a Cafu game server or join a Cafu
internet game, there is of course no harm in blocking access from and to
the internet for Cafu.exe
, but for single-player games, basic access
to the local network is required.
Cafu reports an “Initialization Error”, what can I do?¶
If you see an initialization error similar
to the one in the image to the right, the most frequent cause is that
the drivers for your sound or graphics hardware are outdated or
incomplete (e.g. missing an OpenGL implementation). Please install or
update the drivers for your hardware first, then try again.
If that doesn’t help, run Cafu.exe
from the command
prompt with the
-log console.txt
option. For example:
> Cafu.exe -log console.txt
The contents of the newly generated file console.txt
might give you
a clue about why the initialization error occurred. If it doesn’t,
please post both the error message and the contents of the
console.txt
file at our forum or
mailing-lists.
Note that you can run
> Cafu.exe --help
to see a list of all available command line options. They might be useful to work around the problem, and if you post at the forums, we might ask you to try some of them to further narrow the problem down.
Why do you use OpenGL? I think that DirectX is better.¶
Here are some features of OpenGL that made us choose it as the main rendering API:
- very well documented,
- portable and available on many platforms,
- simple to use,
- independent industry standard,
- powerful extension mechanism that makes it possible to support the latest features of new 3D graphics boards immediately.
You may also find this blog message interesting. 😉
Why is the image quality low? How can I improve it?¶
In normal operation, the Cafu engine provides state-of-the-art image quality that is achieved by employing the latest methods in rendering technology. However, if the image quality is lower than you expected or not as good as shown in the reference screenshots at the Cafu website, these are the common causes for reduced image quality:
- If your graphics board is of an older make and model, it might not have a programmable GPU. Programmable GPUs however are required for rendering the sophisticated image effects of the Cafu engine. As a consequence, if Cafu has detected that no programmable GPU is present on your system, it automatically falls back into the best compatible mode that still works on your system. Normally you should also see an info message about this situation, but it is easy to miss the message. Unfortunately, the fall-back mode cannot provide the image quality that programmable GPUs can provide, as then the lighting and shadows have to be computed per-vertex rather than per-pixel, or their effects even have to be disabled entirely. In this case, you will see no dynamic lighting and no shadows at all. If this situation applies to your system, nothing can be done about it but getting a more recent graphics card.
- The texture detail in the initial options dialog is only set to “medium” quality by default. We have chosen that setting in order to not disappoint the FPS freaks among you, because higher quality normally also reduces the FPS. You can set the texture detail to the “high” setting in order to get higher texture resolution and thus higher image quality. Please note that the “high” quality setting can sometimes considerably lower the frame-rate, depending on the details of your graphics board. You may also want to read the other FAQ about low FPS in this regard.
- The default display resolution of Cafu is 1024*768. That setting has been proven a good compromise between image quality and frame-rate, but you might increase it within the console in order to increase the image quality. 2048*1536 looks really cool, but then the FPS is also lower. 😉
- Some graphics boards with early generations of programmable GPUs are inherently limited in the image quality that they can provide (at a reasonable performance). For example, GPUs that are based on the NV2X series of NVidia GPUs do show specular highlights that look “blocky”. Nothing can be done about that (except getting a more recent 3D board with at least NV3X or ATI Radeon 9600 or higher support).
Why is the frame-rate (FPS) low? How can I improve it?¶
During the past few years, many people have become used to use 3D engines that employ relatively old rendering technologies on relatively new graphics accelerator boards. This combination, observed in games like Counter-Strike, Quake3 and similar, achieved impressive frame-rates (often a hundred FPS and more) and fluid display updates.
The difference with Cafu is that Cafu employs dynamic, per-pixel lighting and shadows. The underlying rendering techniques are much more sophisticated than previous rendering methods, and relatively new. Despite a thoroughly optimized implementation, these techniques inherently cause lower frame-rates than older the techniques. In fact, if you compare Cafu to comparable 3D engines that are in the same category (only very few are, like Doom3), Cafu beats surprisingly well. ;)
There are many factors that have an effect on rendering performance. You can tweak some of them in order to manipulate the frame-rate, but the actual change in frame-rate much depends on your computer system and its components. Some of the suggestions below may even have no observable effect on your system at all. This is because every system has a different bottle-neck, and only finding and removing the bottle-neck yields the greatest effect.
Here is a list of options and suggestions that might help with the performance. You may simply try them out, and see what works best for your system. However, please note that most of these options will buy you faster rendering at the cost of decreased image quality.
- Vertical synchronization.
- People frequently report that their frame-rate seems to be capped to 60 or 30 (or another multiple of 15) FPS. This is usually because vertical synchronization is enabled for your graphics board. Please see the Wikipedia article at Vertical_synchronization for technical details on the matter. Find the related setting in the control panel of your graphics driver to disable the vertical synchronization. Your graphics driver and board will then render the frames without the delay inherent to vertical synchronization, which in turn increases the FPS.
- Video memory and texture size.
- If your graphics board has too little video memory to store all the textures simultaneously that Cafu needs for rendering a single frame, the FPS usually suffers significantly. In this case you can set a lower texture quality in the initial Options dialog. This effectively scales all textures down to not exceed a maximum size, and therefore improves the chances that they all fit into video RAM simultaneously. Another option is to add physical memory to your graphics board. 128 MB normally work well, 256 MB are even better and can store the textures even in maximum resolution.
- Display resolution.
- The default display resolution of Cafu is 1024*768. That setting has been proven a good compromise between image quality and frame-rate, but you might decrease it within the console in order to increase the frame-rate. Reducing to 800*600 or even to 640*480 helps a lot.
- Pixel fill-rate.
A common reason for low FPS is that dynamic lighting and shadows consume a very high pixel fill-rate. Besides reducing the display resolution as mentioned above, an effective way to improve FPS in this case is to turn dynamic lighting and shadow effects entirely off. One way to achieve this is to set the
cl_maxLights
console variable to0
. This can be done in the game console or by putting the statement .. code:: luacl_maxLights=0;into yourconfig.lua
file.When Cafu is run from the command-line, it is also possible to specify a renderer DLL that makes use of less graphics features. For example, you might try the OpenGL 1.2 renderer in order to increase the FPS:C:\Cafu-9.06> Cafu.exe -clRenderer ..\Libs\build\win32\vc8\release\MaterialSystem\RendererOpenGL12.dll
Developer FAQ¶
Is Cafu right for our game of genre “…”?¶
Variants of this question include:
- Can we use Cafu to make a MMORPG?
- Is Cafu fit for our 3D strategy game?
- Will we able to implement our car racing game with Cafu?
While we would love to provide you with a clear and authoritative “yes” or “no” answer to these questions, that is easier said than done:
When you ask one of these questions, you usually have a clear mental image already on how your game should look like – an image that we don’t have, because often we know way too little about your project: your plans, your team, your skills (modelling, mapping, scripting, programming, …), your deadlines, etc. Not knowing what you really want and if you’re ready to – for example – writing material shaders or making changes to the C++ source code is what makes this question difficult to answer.
However, there is an alternative that is much better than any statement we could make: Familiarize yourself with Cafu, try it yourself, and evaluate if it is right for your needs.
For example, download and run the latest demo. Explore the TechDemo map. Then try making a small map of your own, or edit one of the included maps in the editor. Browse the scripts and source code. If there are problems or questions, ask.
Not only will you become familiar with the Cafu details, you will also be able to form a very competent opinion about Cafu’s suitability for your project.
Where are the Visual Studio project files?¶
In the development of Cafu, an important consideration is the build process that turns the source code into executable programs. This build process is a challenge in its own right, because it must work
- on all supported platforms (currently Windows and Linux, soon MacOS, too),
- with several compilers (and several versions of each),
- in several variants (32- and 64-bit; debug, profile and release),
- possibly with multiple combinations of the above, simultaneously on the same computer,
- with all external libraries,
- in changing environments (e.g. variable number of game libraries),
- flexibly, robustly and easily configurable for our fellow developers and users.
Achieving these goals with Visual Studio solution files on Windows (and possibly Makefiles on Linux) is a maintenance nightmare that borders on the impossible. For these reasons, we have chosen to use SCons as the build system for the Cafu Engine. SCons meets the above requirements, and it can still be used automatically and conveniently from most text editors.
Alas, we realize that having true Visual Studio project and solution files (and similar native files for other IDEs) would still be nice to have. We therefore started looking into these programs:
These all look very promising, but each has problems of its own and until today nobody ever finished a complete, working solution. If you would like to help improving the situation, it would be very welcome.
What is the maximum number of network players?¶
There is no hard limit built into Cafu, but the general rule is that in the worst case, updates of everyone must be distributed over the network to everyone else. That means that the overall network load (on the server) roughly climbs with the number of players squared.
Fortunately, the Cafu network code is able to cut the network load significantly in many cases:
- Each network message is very small from the beginning, and additionally compressed.
- The Cafu server knows “who can (potentially) see who”, and optimizes all cases where updates would be sent that cannot be observed by the receiving client.
With these features, Cafu can handle a large number of players in a single level all at the same time. We have demonstrated that connecting 8 clients over the internet is possible without problems (and with some bandwidth left) – and that was several years ago over a slow ISDN (64 kbit/s) Internet connection.
How can I clone the Cafu source code repository?¶
You can clone the Cafu source code repository like this:
> git clone --recursive https://bitbucket.org/cafu/cafu.git Cafu
Also see Getting Started with the Cafu Source Code for more details and https://bitbucket.org/cafu/cafu, where you can browse the repository online, create forks, submit pull requests, and find additional help texts.
How do I start a new game (MOD) project?¶
This is now explained in its own section in the documentation: See Starting your own Game for details.
How do I dynamically reload the map script in-game?¶
While you’re developing a script for one of your maps, it can be a very helpful shortcut to reload the map script while the game is running, without interrupting it. This avoids the normally required cycle of leaving and re-starting the map.
As a preparatory step, add a function like this to your map script:
-- This function reloads and runs this script again.
-- It is useful for working with and testing the script "online",
-- i.e. while the game is running and without reloading the map!
function reloadScript()
-- Adjust the path in the next line as required!
dofile("Games/DeathMatch/Worlds/BPWxBeta.lua");
Console.Print("Reloaded the map script.\n");
end
Then, at the Cafu in-game console, enter
runMapCmd('reloadScript()')
to dynamically reload the script.
In theory, you could combine these two steps into one, using something
like runMapCmd('dofile(“…”)')
, but that is even harder to type than
the version above, and less flexible. (We realize that the entire
runMapCmd(…)
business is not optimal. Suggestions for making this
more convenient are welcome.)
Note that if you use this technique, it can be helpful (but is not
required) to understand how it works: The map script “lives” inside a
Lua state that is initialized together with the map. (The in-game
console has an entirely separate Lua state, which is why
runMapCmd(…)
is needed.) The above commands essentially run
dofile(…)
in the context of the maps Lua state, which in turn
re-runs the map script.
Where can I learn more about 3D programming or game engines?¶
There are many available resources regarding 3D engines and related their subjects, both online and offline in the form of traditional books and papers. The following list is neither complete nor up-to-date, but we hope that it serves as a starting point for your own investigations into the matter:
- NeHe OpenGL Tutorials Excellent OpenGL tutorials for beginners to the advanced.
- http://www.opengl.org The official OpenGL website, and the first place to search for information about OpenGL.
- “Visibility Computations in Densely Occluded Polyhedral Environments” (1992) Seth Teller’s dissertation about Potentially Visibility Sets (PVS): a common data structure in modern 3D engines that speeds up rendering.
- BSP-FAQs Introductory information about BSP trees.
- “Computer Graphics, Principles and Practice” by Foley, vanDam, Feiner & Hughes. Some say this is the bible of computer graphics – and it’s true. It covers nearly everything there is to know. An excellent reference, but have a look into the table of contents before buying it.
- “Radiosity and Realistic Image Synthesis”, Michael F. Cohen and John R. Wallace. Morgan Kaufmann Publishers, Inc., San Francisco, California.
- “Radiosity. A programmers perspective.”, Ian Ashdown. John Wiley & Sons, Inc., New York, N.Y.
- “Zen of Graphics Programming, 2nd edition” by Michael Abrash. Most of this book is about low level DOS graphics programming (outdated now, but good nonetheless). The final chapters are a collection of Abrash’s articles that appeared in the “Dr. Dobbs SourceBooks” series. They contain information about BSP trees, span sorting, etc.
- C++ FAQs by Cline, Lomow, and Girou; Addison-Wesley. Available online and as a book.
- “Effective C++, Third Edition” by Scott Meyers.
- The C++ Programming Language by Bjarne Stroustrup.
- “Programming in Lua, Second Edition” by Roberto Ierusalimschy. The first edition of this book is also available online.
Installation, Initial Configuration and De-Installation¶
Installation¶
The CaWE editor is included with the regular Cafu releases, and as such
requires no explicit installation: After unzipping the packed file,
simply change into the Cafu-x.y
directory. Under Windows, then
double-click on RunCaWE.bat
. Under Linux, click CaWE-run
in the
Projects/Cafu/
sub-directory.
First-Time Configuration¶
This section is relevant to CaWE releases before February 2008 (version 8.02) only. If you have version 8.02 or newer, the initial setup is fully automatic and you can skip this section safely. You may still check out the Configure CaWE Options dialog anytime later.
CaWE requires some basic configuration for normal use, and thus asks you for providing at least one game (or “MOD”) configuration when it is first run:
After clicking on OK, CaWE will automatically show you the related configuration dialog.
Here, click on Add New for adding a new game configuration. You will then be asked for the desired name of the new config.
You can enter anything here, i.e. normally something that reminds you what MOD this config is related to, like “Cafu DeathMatch”.
- Next you have to fill-in where the Game Data File is located. This is
a file with
.fgd
suffix. One such file is already provided with the Cafu package: theDeathMatch.fgd
file in theProjects/Cafu/Games/DeathMatch
subdirectory. Click on the related Browse… button and locate the file. Finally, fill-in the rest of the dialog appropriately such that it eventually looks like this. The paths will of course be different for you, depending on where you installed the Cafu package and its version. See the next step however for an alternative setup.
Alternatively to the previous step, you can also fill-in relative paths as shown in this image. This is the preferred method, because it works better with future versions of CaWE, makes upgrading to a newer version of Cafu and CaWE easier, solves some problems with map compilation some people were reporting, and will become the default with future releases of CaWE! Please note that under Linux, you have to use forward-slashes as the path separator (e.g.
Games/DeathMatch
) and executable files must be referred to like e.g../CaLight
.
All settings in this dialog can be revised later at any time via the File → Configure CaWE… menu. Adding new or additional game configurations at that time may however require to restart CaWE for the settings to take effect.
De-Installation¶
CaWE, as all other Cafu related software, has been designed to interfere with your computer and operating system as little as possible. In general, it is enough to delete the directory that the packed file was unzipped to during installation, and all traces of CaWE are gone.
There is one exception though: When run, CaWE stores your configuration settings in a newly created directory. This directory is located in the “home” directory of the current user. The exact place on your harddisk depends on your OS and even on its version, but CaWE states the full path to it both in the Configuration dialog (General tab), and in the About dialog box that is accessible via the Help → About menu.
Getting Started¶
Introduction to Editing¶
Brushes¶
Do you know how a Lego model or a real house is built from bricks? Invidividual, small bricks are combined to form a complex architectural structure. CaWE works principally in the same way, and thus if you can visualize how individual bricks form a model or a big building, you will find it easy to grasp the concepts behind CaWE.
In CaWE, the bricks are called brushes, and they come in several shapes: blocks, wedges, cylinders, pyramids etc. Moreover, you can modify the default brushes in many ways. They can be scaled, sheared, mirrored, cut in pieces, carved and so on. You can create an arbitrary big number of these brushes in any shape you like, and use and combine them for building the matter that forms your world: walls, floors, roofs, furniture, rocks, … . Brushes eventually get materials assigned that represent the surface properties of that brush, as for example rock, glass, concrete, sand or water. The creation of brushes is detailed at The New Brush Tool.
Bezier Patches and Terrains¶
Modelling really complex surfaces can be difficult with brushes alone, especially if the surfaces should be curved, organic, or very big. Cafu and CaWE therefore provide two additional basic elements that complement brushes: Bezier patches are curved surfaces that you can imagine like bent or stamped metal plates. They can be used to model pipes, curves, smooth archs, and many other organic objects. The creation of bezier patches is detailed at The New Bezier Patch Tool. Terrains are similar, but as their name suggests, aim at surfaces that are much bigger and more irregular. They’re also treated specially by the engine and have very high performance. The creation of terrains is detailed at The New Terrain Tool.
Entities¶
Entities define and represent all other interesting things in a world, and they come in two flavours:
- Point-based entities
- exist at a specific coordinate in space and can be thought of as a reference point. Although these entities may refer to objects that actually have a volume, for example a monster, they are only treated as points in CaWE, and the Cafu engine provides the volume later in the game. An example is a monster entity: In CaWE, it just represents the point where the monster will be, in Cafu, it will acutally be there.
- Brush-based entities
- are related to at least one brush or bezier patch and thus have a volume. Examples for brush based entities include doors and platforms, bodies of water, area triggers, etc.
The creation of entities is described in the New Entity tool documentation. A list with a description of all available entity types can be found in the Entity Guide.
Static Detail Models¶
While static detail models are really nothing more than (point-based)
entities of type static_detail_model
, they provide another powerful
means to augment the detail in your world in a way that is not easy or
even impossible to achieve with brushes, bezier patches and terrains
alone. Such models can be imported from your favourite 3D modelling
program, they can be arbitrarily complex, and they can for example be
under the control of a level-of-detail system. Examples include models
for furniture, statues, household or laboratory inventory, vehicles,
etc.
Putting it All Together¶
By combining these simple components, you can create stunningly virtual worlds whose number of variants is virtually unlimited. Starting with a rough outline of brushes and possibly terrains, you can fill in architectural detail with other brushes, patches and entities. Eventually you will populate your world with more entities that bring your creation to life.
The final step in making a world is compiling it so that it can be run with the Cafu engine. This is a quite complex process that precomputes visibility, lighting and many other details. However, CaWE has a great built-in facility to make the compilation process as easy as possible for you. The article Compiling Maps for Cafu has more information about how CaWE assists in compiling maps.
The Main Window User Interface¶

2D and 3D Views¶
The 2D and 3D views are the center of the activities when you work with a map. They have a number of features that make working with them very comfortable and straightforward.
In order to familiarize yourself with the material in this section
quickly, we recommended that you try it out and reproduce it with one of
the example maps that come with Cafu. Use the File → Open… menu for
loading a map from the DeathMatch/Maps
directory, e.g.
Kidney.cmap
.
By default, the main window is divided into three views that show your map from different sides and perspectives. In the center is the 3D view, which shows the map as a perspective rendering. The two 2D views show the map from the top and from the side like an architects plan.
The view windows¶
Each view is a window
whose title bar indicates the type and render mode of the view. You can
maximize, minimize or close each view window with the buttons in the
upper right corner. In order to create a new 2D or 3D view, choose
View → New 2D view or View → New 3D view from the main menu.
By clicking and dragging a windows title bar, the views can be docked,
undocked and arranged as you like. Press Ctrl
while dragging a
window in order to keep it floating (prevent it from docking to one of
the highlighted dock positions).
The active view¶
A view is activated when you move the mouse pointer into its window.
Keyboard input, menu commands and status bar information all refer to the most recently activated view. For example, if you want to navigate the views with the keyboard as presented below, just move the mouse pointer into the desired view window, and all keyboard input will be directed to it.
Changing the view mode¶
In
order to change the mode of a 2D or 3D view, use:
- the
Tab
key, - the
Shift+Tab
key, - or the context menu (right mouse button click).
The 3D views show the map in different render modes, for example “wire-frame”, “flat colored”, “edit materials” or “full materials”:
Note that render mode “3D Edit Mats” often looks much like “3D Full Mats”, but whereas the latter shows the materials in their “natural” appearance (as in the game engine, e.g. translucent, distorted, invisible, black, etc.), “3D Edit Mats” shows plainly textured surfaces instead. This can be very helpful for seeing the materials properly for editing purposes.
Video¶
This video demonstrates the most important concepts for navigating the 2D and 3D views.
The Material Browser¶
One of the most important
dialogs when working with CaWE is the Material Browser. Materials are
used by many tools, e.g. when new brushes, bezier patches or terrains
are created or when the surface properties of such an element are
edited. The Material Browser displays all available materials as
thumbnails and allows you to select one for subsequent operations with
the tools.
The image to the right shows the essential buttons for opening the Material Browser. In most cases and with most tools, you’ll use the default button in the left Material Toolbar for opening the Material Browser, but the “Edit Face Properties” tool has an own dialog that has its own button.
Please note that when you press the Browse
button for the first
time during a CaWE session, CaWE has to cache-in the available
materials all at once. Therefore it may take a short while until all
materials are loaded. This will only happen once during a CaWE session,
and pressing the Browse
button another time will open the Material
Browser instantly.
Your First Map¶
The flash tutorial below introduces you to the basic features and concepts of CaWE and demonstrates how you can create your first map. It starts with opening a new map file in the Cafu World Editor CaWE, then walks you step-by-step through the construction process. At the end, the map is compiled and run in the Cafu engine.
The tutorial assumes that you have already installed CaWE and completed the initial one-time configuration as described in section Installation, Initial Configuration and De-Installation.
Although the tutorial does not require any previous knowledge, it is helpful to read the preceding “Getting started” chapters either before starting or while working through the tutorial.
Tutorial Contents Overview¶
- Verification of essential settings in the CaWE Options dialog.
- Opening of a new map file in which a single room will be built.
- Creation of the first brush for the floor.
- Use of the Material Browser to select an appropriate material.
- Use of the New Brush tool to create a brush outline.
- Dragging of the outline and updating of the 3D camera position.
- Creation of the second brush for the left wall analogous to the
first.
- Zooming in the 2D views and more advanced manipulation of the brush outline.
- Creation of the third brush for the right wall by employing the clone-dragging technique of the Selection tool.
- Creation of the fourth brush for the back wall by using the “Copy”
and “Paste” items of the
Edit menu.
- Includes the transformation of a selected object to (re-)shape it as desired.
- Creation of the fifth brush for the front wall as a copy of the back wall by use of the related keyboard shortcuts.
- The ceiling brush (sixth brush) is created by clone-dragging it from the floor brush.
- Application of a sky material to the ceiling brush as a post-creation step.
- Demonstration of the difference between the render modes “3D Full Mats” and “3D Edit Mats”.
- Placement of an
info_player_start
entity near the center of the room, using the New Entity tool. - The map is compiled and run in the Cafu engine.
Map Editing Tools¶
The Selection Tool¶
The Selection tool allows you to select objects like brushes, entire entities or bezier patches in your map and move, scale, rotate or shear them. Apart from these functions directly activated by the Selection tool, CaWE provides a lot more functions that are related to selected objects. Since these functions are only usable with one or more objects, the Selection tool is a very important instrument to create maps.
You can activate the Selection tool by clicking on the related icon
marked in the left screen or by pressing the SHIFT+S
keyboard
shortcut.
Selecting objects¶
To select an object, click the object once. In the 3D view, click on any surface that is part of the object to select it. In the 2D view click either on an edge that is part of the object or on its center marker.
In the 3D view, the surface of the object will be changed in color and its edges are colored yellow to mark it as selected. In the 2D view, the edges of the selected object are colored red.
To select one or more objects you can also drag a selection box in a 2D
view window. Releasing the mouse button opens the selection box, but
does not select the objects yet. You can move and scale this selection
box until it covers all objects you want selected. To eventually select
the objects, press the ENTER
key. This way all objects that are
covered whole or partially by this selection box are selected. Note that
you can also scale the selection box in another 2D view to create a
spatial selection box and narrow down the selected objects.
You can change the behavior of a selection box in the
Configure CaWE Options dialog
at the 2D Views tab. Automatic infinite selection in 2D windows
(no ENTER) enables you to drag a selection box and instantly select
all objects by releasing the mouse button instead of pressing the
ENTER
key. This way however you loose the ability to open a spatial
selection box. If Selection box selects by center handle only is
activated, only objects whose center handle is covered by a selection
box count as selected objects.
Another way to select more than one object is to select objects while
pressing the CTRL
key. This way you can choose as many objects as
you want and perform an action on all these objects simultaneously.
You can select all objects in a map by clicking the Select All option from the edit menu. To deselect all objects, use the Select None option from the edit menu.
You can also deselect all selected objects by pressing the ESC
key,
which clears the selection.
Working with selected objects¶
Now that one ore more objects have been selected you can perform actions on them.
Moving and Cloning objects¶
By clicking inside the selection box of an object, you can drag it in a
2D view and move its position to a new location. If grid snapping is
activated, you can ignore it while moving the object by pressing the
ALT
-key. This also works with the transformations described below.
You can also move objects with the “arrow” keys, if you select the Arrow keys nudge selected object/vertex option in the Configure CaWE Options dialog under 2D Views.
An easy way to duplicate objects is using the Clone function while
moving an object. Simply move your object as described above, but before
releasing the left mouse button to move the object, press and hold the
SHIFT
key. In this way a clone of the object is created at its new
location. Note that cloning an object while moving it with the “arrow”
keys is not supported.
Tranformation modes¶
To resize, rotate or shear an object you have to select the appropriate transformation mode. You can switch between the 3 modes by clicking inside the selection box of the object you want to transform. Different transformation modes are marked by handles at the edges and vertices of the selection box.
Resizing an object¶
A dashed rectangular box is drawn around a selected object by the editor (this box is only visible if the object itself isn’t rectangular). The resize mode is marked by white squares at the edges and vertices of this box. By moving the mouse over one of these squares and dragging this square by holding down the left mouse button you can resize the object in the direction of the square you clicked on.
Rotating an object¶
The rotate mode is marked by white dots at the vertices of the box.
Moving the mouse over one of these dots and dragging this dot by holding
down the left mouse button rotates the object smoothly. It is also
possible to rotate the object in multiples of 15 degrees by pressing and
holding down the SHIFT
-key while rotating an object.
You can change the default behavior to rotating in 15 degree steps if
you select the Default to 15 degree rotations option in the
Configure CaWE Options dialog
under 2D Views. If this option is select, pressing SHIFT
will
allow you to rotate the object smoothly.
Shearing an object¶
White squares at the edges of the selection box mark the shearing mode. By left clicking on a square and moving the mouse while holding the left mouse button down this edge can be moved in two directions along its own axis and in this way the object is deformed.
Deleting an object¶
To delete a selected object just press the DEL
-key on your keyboard
or choose Delete from the
Edit menu.
More¶
There are a lot more things you can do with selected objects. These additional functions are explained in the documentations of the Edit menu, Map menu, View menu and Tools menu.
The Tool Options Bar¶
Once the Selection tool is activated, its option bar is visible above the view windows. This bar contains selection parameters and buttons for further functions related to selections.
- Ignore Groups
- This option specifies if grouped objects are selected as a group (selecting one object selects all objects) or if groups are ignored and objects are selected normally even if they are part of an object group.
- Lock Materials
- This option determines if the Material of an object is locked to the object itself and therefore doesn’t change, even tough the object is moved. If this option is not selected the Material is locked onto the point of origin of the world coordinate system and therefore the part of the texture visible on the object may change when the object is moved.
- Group
- This button puts two ore more previously selected objects into a group. Grouped objects can be selected all at once by clicking on one object of the group.
- Ungroup
- This button reverts grouped objects back to single objects. This function only works if a group of objects has previously been selected.
- Hide
- Hides all selected objects from the view windows. The objects are not deleted, but simply not displayed, which is particularly useful when working with big maps that contain a lot of objects.
- Hide Other
- Hides all objects except the selected objects.
- Apply Material
- Applies the material that is currently selected in the materials bar to the selected object(s).
Selection tool keyboard shortcuts¶
SHIFT+S
:- Activates the Selection tool.
ENTER
:- If a box selection is opened → selects all objects that are part of the box selection .
ESC
:- If a box selection is opened → closes the box selection.
- If an object is currently resized, rotated, sheared or moved → move object back into original position and form.
- If objects are selected → deselect objects.
DEL
:- Deletes the selected object(s) from map.
CTRL
:- If in selection-mode → add new selected objects to selection list instead of removing old selection and only selecting clicked object.
ALT
:- While moving or cloning an object → ignore grid snapping and move object smoothly
- While tranforming an object → ignore grid snapping and transform object smoothly
SHIFT
:- If Rotating an object → rotate in multiples of 15 degrees.
- If moving an object → object is cloned first then moved, so original object remains in place.
Page up
:Page down
:- If last select click covered more than one object → cycle trough objects.
The Camera Tool¶
In section 2D and 3D Views we have explained how 2D and 3D views work and how you use them to explore and navigate the map. We have also mentioned (albeit briefly) that each 3D view has a “camera” assigned: A camera specifies a viewer origin (sometimes also called “eye position”) and an orientation (“direction”). When you use the mouse or keyboard to look, move, pan, zoom or orbit in a 3D view, you actually manipulate the related camera position and orientation, and the 3D view in turn uses the updated camera details to update the scene rendering.
We believe that the mouse and keyboard camera controls of section 2D and 3D Views are so powerful and easy to use that you will use them virtually all the time.
The purpose of the Camera tool is to add the less frequently needed extras: You can create new cameras (and assign them in turns to 3D views), and edit their origins and orientations in the 2D views.
To activate the Camera tool, click on the related icon in the tool bar
or press Shift+C
.
Camera display in 2D views¶
When a tool other than
the Camera tool is active, cameras are shown with a gray dot at their
origin and a gray line that indicates their viewing direction
(orientation).
When the Camera tool is active, the cameras
are displayed in colors so that they are easier to spot in the map.
Creating and deleting cameras¶
To create a new camera, press
and hold the
Shift
key, then use the left mouse button to drag a
line in one of the 2D views. The starting point of the line becomes the
camera origin, the line itself defines the orientation.
Having multiple cameras distributed at key locations in the map can facilitate map navigation a lot, as a 3D view can cycle through all available cameras as described below.
At this time, cameras that are not assigned to a 3D view are not saved with the map; they are lost when the map is closed. You can manually delete an active camera via the Edit → Delete menu item. The last camera cannot be deleted, as there is at least one 3D view that it is assigned to.
Manipulating the origin and orientation¶
The most powerful and most convenient methods to manipulate a camera are the controls described in section Navigating the 3D views (in addition, the controls described there do not require the Camera tool to be active: they work always).
Sometimes however, it is worthwhile to set the origin and/or the orientation in a 2D view:
Click and
drag the dot in order to move the camera origin.
Alt
key while dragging toggles grid snapping.Ctrl
key moves the line as well (and thus the camera
as a whole). Click and drag the end of the line in order to change the
camera orientation. (The length of the line does not matter. You can
for example drag the end of the line onto the object of interest, to
center it precisely in the related 3D view.)
Alt
key while dragging toggles grid snapping.Ctrl
key moves the dot as well (and thus the camera
as a whole).Switching cameras¶
In order to assign a 3D view (the active 3D
view) another camera, use the Page Up
and Page Down
keys to
cycle through all cameras in the map.
Camera tool keyboard shortcuts¶
Key | Action |
---|---|
Page Up |
Assign the next camera to the currently active 3D view. |
Page Down |
Assign the previous camera to the currently active 3D view. |
ESC |
Quit the camera tool and switch to the Selection tool. |
Shift |
LMB-clicking and dragging in a 2D view creates new camera. |
Ctrl |
Move the camera as a whole when dragging one of its handles. |
Alt |
Temporarily toggle grid snapping while dragging a camera handle. |
The New Brush Tool¶
The New Brush tool is, as its name says, used to create new brushes.
Brushes are primitive objects with a simple structure and come in different shapes, like a block, a cylinder, etc..
Most parts of a map in CaWE are build from brushes, whereas more complex structures are built as a combination of brushes.
The Brush Tool can be activate by clicking on its related icon or by
pressing SHIFT
+B
.
The Tool Options Bar¶
As the New Brush tool is activated, its options bar is visible above the view windows.
Here you can select the shape of the brush you want to create and the number of sides the brush should have. For some shapes the number of sides is fixed (as for example the block shape) and number of sides setting is grayed out.
Creating a new brush¶
To create a new brush you have to drag a box in a 2D view, that represents the height, width and depth of the brush. Since the brush is not created after dragging the box you are still able to move and resize it.
Note that holding down the ALT
key while creating or resizing the
box, you can temporarily ignore the editors snap to grid setting.
To create the new brush you have to press ENTER
. The material that
is currently selected in the
materials bar is automatically
applied to the new brush.
Different Shapes¶
Pyramid¶
A pyramid is shaped like a cylinder, but the top vertices are all in one point. It can have 3 to 32 sides.
Arch¶
An arch with variable values such as wall width, side number and arch span. These values can be configured in a special arch diaglog.
- Wall Width
- Thickness of the archs wall.
- Number of Sides
- Number of pieces the arch consists of.
- Arc
- Span of the arch in degree.
- Start Angle
- Start angle offset.
- Add Height
- Height difference between 2 arch pieces (see screen below).
New Brush tool keyboard shortcuts¶
SHIFT+B
:- Activates the New Brush tool.
ENTER
:- If a brush box is opened → create the brush (only works in a 2D view).
ALT
:- If creating a brush box or moving/resizing it → temporarily deactivate snap to grid
ESC
:- Back to Selection tool
The New Entity Tool¶
The New Entity tool allows you to add both new point-based and
new brush-based entities to your worlds. Please refer to the
Introduction to Editing for a quick
overview on point-based vs. brush-based entities. The
Entity Guide lists and describes all entity types
that are available with Cafu.
The New Entity tool is activated by either clicking on its related
button on the tools toolbar, or by pressing the Shift+E
keyboard
shortcut.

The left half of this bar is relevant for placing point-based entities,
i.e. at New (point) entity type:
you choose the type of the new
entity that is to be created. The right half of the bar allows you to
turn the currently selected brushes into brush-based entites and back.
That is, the Turn into (solid) entity type:
button turns world
brushes into a brush-based entity of the type that has been chosen from
the list to the right of the button, whereas the Back to world
button reverses the process by turning the currently selected
brush-based entity into regular world brushes again.
Placing Point Entities¶
Select the Entity tool.
In one of the 2D windows, click where you want to place your entity. A green box will appear where you clicked. This is where the entity will be inserted.
- Drag the green box to where you want the entity in the other views.
Select the type of entity you want to insert from the “New (point) Entity” dropdown box. I’m inserting an info_player_start.
Put your mouse cursor over one of the 2D views, and press enter. The entity should appear. You should be able to see it in both the 2D and 3D views. Note that other entities are different colours, shapes and sizes.
Placing Brush-Based Entities¶
In this example, I will be adding water to a very simple map. The process is very similar when inserting other brush entities.
Select the New Brush tool.
- In a 2D view, drag out a box the size you want your water to be. Adjust the size in the other 2D views.
- (This step is not necessary for most other entities) Click the
“Browse” button in the texture settings (under the tool icons). When
the viewer pops up, change the filter to “water” (without quotes).
Select one of the materials.
→
- With your mouse cursor over one of the 2D views, press Enter. The brush should be selected if not, select it with the selection tool.
Click the New Entity tool.
On the far right side, select “func_water” from the drop down box. Click “Turn into (solid) entity type”.
Now compile your map, and you should see water!
See Also¶
static_detail_model
are created and how their visual and collision
models are properly set. The second part of the tutorial examines a
collision model by example and summarizes how new collision models are
created.The New Bezier Patch Tool¶
The New Bezier Patch tool is an easy to use tool, if you want to create curved surfaces such as pipes or uneven floors.
A Bezier Patch is in its pure form a plane with a grid of vertices (with variable grid density), that can be moved to change the form of the Bezier Patch.
To activate the tool, use the related icon from the tool bar or press
SHIFT
+P
.
The Tool Options Bar¶
The Tool Options Bar lets you choose from different source forms, that a created Bezier Patch will adopt at the beginning. Possible forms are:
- Flat
- A simple flat plane.
- Cylinder
- A Bezier Patch bent into a cylindric form without bottom or top.
- Open Box
- A rectangular box without bottom or top.
- Half Cylinder
- A Bezier Patch bent into a half cylinder.
- Quarter Cylinder
- A Bezier Patch bent into a quarter cylinder.
- Edge Pipe
- Basic form to easily create edges of pipes.
- Cone
- A Bezier Patch bent into a simple cone.
- Sphere
- A Bezier Patch bent into a spherical form.
- Convex Endcap
- Creates a quarter cylinder convex endcap.
- Concave Endcap
- Creates a quarter cylinder concave endcap.
The Checkboxes with convex endcaps and with concave endcaps determine whether a newly created bezier patch should have fitting endcaps at creation.
The fields width and height define the number of vertices on the two axis of the Bezier Patch. Higher values mean a higher density of vertices.
Note that these options are not available for all basic bezier patch forms.
The Subdivs Horz and Subdivs Vert controls adjust the subdivisions of a bezier patch in x or y direction. A higher value means a more seamless bezier patch surface. You can also use these two controls to adjust the subdivisions of a currently selected bezier patch.
Values of -1 mean, that the number of subdivisions is chosen automatically.
Creating a Bezier Patch¶
To create a new patch you have to drag a box in a 2D view that defines
the size of the Bezier Patch (note that the box has to be spatial even
if you want to create a Flat Bezier Patch). After the box is created
you can then resize it to your liking. Finally press ENTER
to create
the Bezier Patch in its chosen source form.
Forming a Bezier Patch¶
To form a Bezier Patch you have to activate The Selection Tool and select the patch you want to form.
Forming the patch is done by activating The Edit Vertices (Morph) Tool. Now you can see all control vertices of the Bezier Patch in the 2D views as well as in the 3D view. You can drag control vertices in both views to form the patch in the same way you drag vertices of brushes (see here).
In this example the center vertice is selected and moved up in a side view.
Altough only the center vertice has been moved, the Bezier Patch has changed its form creating a smooth bump instead of a peak.
Applying materials to Bezier Patches¶
Materials are applied onto bezier patch surfaces using The Edit Surface Properties Tool.
New Bezier Patch tool keyboard shortcuts¶
ESC
- Back to Selection tool.
ENTER
- If Bezier Box is opened → create Bezier Patch.
ALT
- Temporarily ignore grid snap while creating a Bezier box
The New Terrain Tool¶
The “New Terrain” tool helps you to create new terrains. These
terrains can be very large, have very good rendering performance, and
are specially treated by the Cafu engine.
The “New Terrain” tool is activated by either clicking on its related
button on the Tools toolbar, or by pressing the Shift+T
keyboard
shortcut.

The New terrain heightmap name
determines the file that is used as
the heightmap image that defines the shape of the new terrain. Use the
combobox to select a previously used heightmap file, or use the
Browse
button to select a new file from disk. Note that the
supported file formats include the most common image file formats
(jpg
, png
, tga
and bmp
) as well as Terragen (ter
)
and portable graymap (pgm
) files. Also note that heightmaps need
to be grayscale and need to be power of two + 1. For example, a 512×512
heightmap needs to be 513×513 to work correctly in Cafu. A 1024×1024
needs to be 1025×1025. And so on. The section
Creating Height-Maps for your Terrains
explains how you can create your own height-maps for use here.
The two checkboxes to the right control whether sky walls, a sky ceiling and a floor are created automatically with the terrain. Although terrains are often used for large outdoor areas, they must still exist “inside a room”. That is, terrains must be bounded by brushes that form four walls, a ceiling and a floor. With the two checkboxes, you can control whether CaWE should automatically create such bounding elements for you together with the new terrain (recommended!). You can later always edit or delete the so created walls (they are regular brushes), e.g. in order to make a doorway to some indoor or underground area of your map.
Finally, you have to pick a material for the new terrains surface, which you can conveniently do as usual with the Materials toolbar.
Note that all these attributes determine how the new terrain will be initially created. Of course, you can also review and change all these aspects for existing terrains later.
With everything being setup, you create the new terrain in the same
manner as you create new brushes: Draw a box in the 2D views. The box
determines the bounds of the new terrain, both laterally as well as the
height of the lowest and highest points. When you’re satisfied with the
position and size of the box, press RETURN
or right-click in one of
the views to confirm the terrain creation.
The New Light Tool¶
The New Light tool is used to place light entities and is actually a subpart of the New Entity tool. The difference is, that the New Light tool can only place light entities, whereas the New Entity tool can place all entities.
Lights are used to illuminate a map and come in two forms:
Static lights: These lights are precalculated by the editor when compiling a map. Lightmaps are built to define which parts of the level textures are illuminated and shadowed.
Dynamic lights: These lights are placed in the editor but their illumination and shadow casting is calculated dynamically by the engine during runtime. This makes them perfect to calculate light and shadow with movable objects, which is impossible with static lights. It is also possible to move the light source itself, which makes this a very flexible light source, but has also very high processing costs.
You can activate the New Light tool using the related icon in the tool
bar or by pressing SHIFT
+L
.
The Tool Options Bar¶
In the options bar of the New Light tool you can choose what light you want to create.
There are 2 options available:
- PointLight
- A static light source from which lightmaps are calculated.
- PointLightSource
- A dynamic light source which is handled by the engine at runtime.
Creating a light¶
To create a light source, you can click on a location in the 3D view where the light source is instantly created.
If you click in the 2D views a point is created, which can be properly
positioned before creating the light source by pressing the ENTER
key.
Configuring a light¶
To configure the properties of a light source, you have so select the
light with the Selection tool and choose
Object Properties from the Edit menu or press
ALT
+ENTER
.
The properties for the PointLight include:
- Opening Angle
- Opening angle of this light source
- Intensity red/green/blue
- Intensity of the different light colors
The properties for the PointLightSource include:
- Dyn. light radius
- Radius of light dissemination
- Dyn. light diffuse color
- Color of diffuse light
- Dyn. light specular color
- Color of specular light
New Light tool keyboard shortcuts¶
ENTER
- create light source after placing it in a 2D view
ESC
- switch back to the Selection tool
ALT
+ENTER
- if light source selected → open its properties dialog
The Edit Surface Properties Tool¶
The Edit Surface Properties tool gives you control over the surfaces of Bezier patches and brush faces. You can use it to apply and change materials and modify their scale, shift and rotation on the surface. Sophisticated controls are available to determine these and other attributes of a surface.
The Edit Surface Properties tool can be activated by clicking on the
related icon in the Tools toolbar or by pressing the SHIFT+A
shortcut key.
Left-Clicks: Selecting and Picking¶
A normal click with the left mouse button on a surface (Bezier patch or brush face) in the 3D view accomplishes two tasks:
- it selects the surface (you can see how it becomes highlighted by a reddish overlay), and
- it picks the properties of the surface and updates the values in the related dialog accordingly (the Orientation and Material sections are updated).
As usual, you can hold the CTRL
key to select more than one surface
at a time. Please note that CTRL
-clicked surfaces are selected, but
not picked. That is, only the first selected surface (left mouse button
click without CTRL
) implies the pick operation.
In fact, selection and picking are actions that are independent of each other:
- Both:
- A normal left mouse button click performs both.
- Selection only:
- Holding the
CTRL
key while clicking toggles the selection, but doesn’t pick. - Picking only:
- You can also pick but not select by holding the
ALT
key during the mouse click, which activates the eyedropper mode. The properties of such clicked surfaces will appear in the dialog, but their selection status won’t change.
Finally, you can also hold the SHIFT
key during a left mouse button
click. The SHIFT
key does not add anything special when the click is
on a Bezier patch, but for brush faces, it causes all faces of the
affected brush to become selected. (If CTRL
is not held at the same
time, the clicked brush face will also be picked for updating the dialog
values.) You can combine the SHIFT
with the CTRL
key in order to
toggle the selection status of all faces of the brush.
Brushes that were selected when the Edit Surfaces Tool was activated are automatically changed into face selections.
You can hide the reddish overlay of selected surfaces by checking the Hide Selection Overlay checkbox in the Tool Mode section of the dialog. This improves the visual perceptibility of the surfaces in some cases, which in turn can be helpful when using this tool.
Orientation and Material¶
Once you have selected one or more surfaces, you can modify their orientation and material attributes.
If you have multiple surfaces selected at the same time, the new value of the changed attribute is applied to all of them, while all other attributes are left alone. This allows you for example to replace the material or to set a common scale on a number of surfaces all at the same time, while the individual shift, rotation and other surface aspects are left alone.
Right-Click Application¶
The orientation and material attributes in the dialog can also be applied to surfaces by right-clicking on them. The right-clicked surface needs not be selected for this to work, and all attributes (orientation and material) are applied at the same time. This feature makes the application of the attributes in the dialog to a number of surfaces quick and convenient.
With right-click application, the way in which the attributes are applied to the surfaces can be modified at the Right MB mode choice in the Tool Mode section of the dialog. The following options are available:
- Apply Normal
- Applies the material and the orientation attributes in the dialog “normally” to the surface.
- Apply Material only
- Applies the material, but not the orientation attributes.
- Apply View Aligned
- This mode works like a slide-projector: The material is projected onto the clicked surface, where the base of the cameras view pyramid defines the plane of projection. (Contrary to a real slide-projector though, parallel rather than perspective projection is employed. Variants of parallel projection are also employed by the other apply modes and are more appropriate for the task at hand.) The orientation attributes are also taken into account. This is a great mode for texturing a rocky wall or any other irregular shape (that consists of multiple adjacent surfaces) seamlessly.
- Apply Edge Aligned
- This mode makes sure that when you click on a surface next to the
previously picked one (i.e. left-clicked, possibly with
ALT
), the material is seamlessly aligned across the common edge. This is a worthwhile feature especially when the two surfaces are not coplanar. (It even works when the clicked surface is not immediately adjacent to the other.) (FIXME!) What exactly are the restrictions when Bezier patches are used? - Apply Projective
- Like Apply Normal, but this mode also applies the texture planes U- and V-vectors of the picked surface to the clicked surface. This mode is the generalization of both the Apply Normal as well as the Apply View Aligned modes, and as the underlying technique is a mathematical projection, it is called Apply Projective. Refer to the advanced section below for more technical information. This is the mode of choice whenever you want to texture a Bezier patch exactly like an adjacent brush face. For example, if you have a wall or a floor that is made of both brush faces and Bezier patches, and you want to apply the material on the brush faces seamlessly to the Bezier patches, just pick up the surface attributes from a brush face, and Apply Projective to the Bezier patches.
When SHIFT
is held during a right-click on a brush surface, the
application is performed on all surfaces of the brush.
The button to all Sel. is equivalent to (but more convenient than) right-clicking on all currently selected surfaces with the current Right MB mode setting.
Alignment¶
The materials of selected brush faces (not Bezier patches) can be automatically aligned at the top, bottom, left or right edge of the face by the related button in the Alignment section of the dialog. The material can also be centered or made fit on the brush face. In all cases, the effect is achieved by auto-adjusting the Shift and/or Scale attributes of the selected brush faces appropriately.
( (FIXME!) Re-pick the first selected surface in order to update the dialog attributes! )
The Treat multiple as one checkbox determines whether multiple selected surfaces are treated, with regards to their spatial extends, as multiple individuals or as a single merged one when one of the Alignment buttons is pressed.
Fit on Bezier patches¶
For Bezier patches, the (highly useful!) Fit button works slightly differently than for brush faces: Although in both cases the material will be made “fit” to the underlying surface, Bezier patches are then in a different mode regarding texture-coordinate generation than brush faces.
This is because for brush faces, you could have achieved the same result by manipulating the Scale and Shift manually. With Bezier patches, which can be curved to any shape (e.g. cylindrical or spherical), the same mathematics cannot achieve the same effect, and thus using the Fit button on Bezier patches puts them into Fit mode that yields the desired result.
The essence of Fit mode is that the Scale attributes now indicate the number of repetitions of the material along the surface, rather than the number of texels per world unit as usual.
Because of this difference, while applying the surface properties of such Bezier patches to other Bezier patches is straightforward and intuitive, applying the same attributes to brush faces is sometimes not possible without distortion. Such cases are easily fixed though by clicking and editing the affected brush surface.
The line “Mode: Fit” near the Orientation controls indicates that the current surface values were taken from a Bezier patch that was in Fit mode.
You can “revert” the mode of such a Bezier patch surface back to normal by picking the surface attributes of a brush face and applying them to the Bezier patch in Apply Projective mouse-button mode.
Plane Indicators¶
The wrt. World axes checkbox indicates whether the texture plane of the surface happens to be parallel to one of the three major planes through the world axes.
The wrt. Face plane checkbox indicates whether the texture plane of the surface is parallel to the spatial plane of the surface. This is never true for Bezier patches (they in general have no inherent spatial plane), and normally always true for brush faces; however you can use the Apply Projective right-click apply mode in order to force any texture plane onto any surface.
How do I …¶
… texture brush faces?¶
Individual brush faces are easily textured by left-clicking them to pick their attributes into the dialog. Then you use the controls in the dialog to directly modify the orientation, alignment, etc. The changes become immediately visible on the selected face in the 3D view. You may check the Hide Selection Overlay checkbox in order to hide the selection mask.
For texturing a larger area of your map where many brush faces are to be textured in a similar style, you should first texture one of the surfaces as described above, then use the Right-Click Application feature to apply the texture to all desired surfaces in the 3D view quickly. Make sure that you understand the apply modes of the right mouse button in order to get the best out of them.
Repeat this with other textures of your choice, and fine-tune them individually in the end.
… texture Bezier patches?¶
This is as easy as texturing brush faces, but sometimes Bezier patches are textured for a specific purpose:
Bezier patches that are a part of a floor or ceiling plane are often to be textured so that the transition to the adjacent brush is seamless. This is easily achieved by picking the texture from the nearby brush, select Apply Projective as the Right MB mode, then right-click apply the material to the Bezier patch.
Bezier patches that represent bulges, dents or small terrains that are expected to blend seamlessly into neighboring brushes are also well approach by the projective or view aligned apply modes.
Pipes, pillars, wall arches and similar objects are best textures by using the Fit alignment button. The material then covers them naturally, and you can conveniently set the number of texture repetitions by the Scale values in the dialog.
… deal with the “Picking […] is not possible” message?¶
This message can occur when picking (left-clicking) Bezier patches that were created with previous versions of CaWE, or Bezier patches that were imported from other games and file formats. Such Bezier patches got custom texture-coordinates assigned and are in “Custom” tex-coord generation mode; you may refer to section Advanced Considerations below for more details.
Nothing is inherently wrong with Bezier patches in Custom mode, you just cannot pick their surface properties and apply them to anything else. As soon as you assign surface properties from another brush face or Bezier patch (that is not in Custom mode) though, the Custom mode is overwritten with the newly applied properties, and the Bezier patch acts normally then.
… deal with “Mode: Fit” orientation attributes?¶
Bezier patches that are newly created or whose material has been applied using the Fit button are in the “Fit” texture-coordinate generation mode, whose essence is that the Scale attributes now indicate the number of repetitions of the material along the surface, rather than the number of texels per world unit as usual.
Refer to section Fit on Bezier patches above and Advanced Considerations below for more details.
Advanced Considerations¶
The Edit Surface Properties tool has been written in order to make the texturing of brush faces and Bezier patches simple and consistent. However, brushes and patches are inherently different, and therefore you can do things with the one that you cannot do with the other, and vice versa. This is true for geometric modelling but also has consequences for texturing them with this tool. Moreover, the tool offers several advanced ways to apply textures to the different kinds of surfaces, and you might be interested to learn more on how they work.
This section first describes the texture-coodinate generation modes that the tool internally uses, then explains the details of the plane projection mode.
The Tex-Coord Generation Modes¶
Each surface (brush face or Bezier patch) is internally assigned a texture-coordinate generation mode that determines how the texture-coordinates at the vertices of the surface are computed:
- Plane Projection
- is the most frequently used and most important mode. It is always used on brush faces (which can never use another mode), but it can also be used on bezier patches. The Plane Projection mode is explained in greater detail below.
- The Fit mode is special to Bezier patches, and can only be used on them. Whenever you press the Fit button in the dialog, the tex-coord gen. mode of the selected bezier patch is changed to this mode. It is typically used on pipes, columns and similarly shaped objects, making sure that the material naturally fits into the surface of the object. The number of repetitions can be given by the “Scale” parameter in the dialog, which therefore has a different meaning from the Plane Projection mode. (When the Fit button is pressed for brush faces, a visually similar operation is performed in Plane Projection mode.)
- Custom
- is reserved for future use and applies whenever the user has specified custom UV texture-coordinates for the vertices of a surface that cannot be achieved with the other modes. It is also used on Bezier patches that were created when the CaWE map file format did not support the tex-coord generation modes. This is true for older CaWE maps and for maps that are imported from other games or file formats.
When you pick the attributes of a surface into the dialog, it also remembers the tex-coord generation mode of that surface. Picking is only possible when the surface is in Plane Projective or Fit mode, never in Custom mode. Applying previously picked attributes to another surface (either a brush face or Bezier patch) is always possible, although applying “Fit” mode attributes to brush faces (which can only be in Plane Projective mode) can yield unexpected results. (FIXME!)
Picking and therefore applying attributes that are associated with Custom mode to any surface is not possible at all.
The Plane Projection Mode¶
In Plane Projection mode, the texture-coordinates at the vertices of the desired surface are determined by an orthogonal projection of a texture plane P onto the vertices. The parameters of the plane are determined by the Orientation controls in the dialog.

The texture plane P is indicated by the dark blue color, its normal vector in dark green. The x-axis span vector is indicated in red, as well as integral multiples of its length in both directions. The y-axis span vector is not included in the image, as it points up or down, into or out of the figure.
A texture plane is obtained by picking a surface in Plane Projective mode. For example, texture plane P in the image was obtained by left-clicking on the highlighted face of brush A.
Note that the x-axis represents one width of the material that is to be applied to the surfaces: If you change the Scale values in the dialog, the length of the x-axis (and y-axis) changes, too, implying that more or fewer repetitions of the material span a given distance in the world. Changing the Shift values in the dialog moves the x-axis arrow and its multiples along the plane. If rotation was applied, the x-axis would rotate “into” our “out of” the image, while the y-axis became visible.
In the dialog, the wrt. World axes and wrt. Face plane checkboxes indicate whether the dialogs last picked plane happens to be parallel to the major world axes and/or parallel to the physical surface of the picked-from face.
The dotted lines indicate how the material would be applied from the texture-plane to the objects surfaces. At object A there is a natural fit, because integral multiples of the material match the extends of the object. Object D is also natural case, but the material would appear shifted on it’s surface. You would have to modify the Shift attributes in order to align it with the extends of the surface.
Note that objects B and C are special cases: When you normally apply the attributes of plane P to their surfaces, P is moved and rotated first so that it gets parallel to the desired surface. This is what the Apply Normal mode of the right mouse button does.
The Apply Projective mode however does not include the additional move and rotate step, and applies texture-coordinates directly as indicated in the figure. This is sometimes a very useful feature in order to achieve certain effects, for example with texturing Bezier patches in some cases.
The Apply View Aligned mode works similarly, except for the fact that plane P is always forced to be parallel to the base of the view pyramid of the currently active 3D camera.
The Edit Terrain Tool¶
SHIFT+F
keyboard
shortcut.General¶
The tool is mainly composed of three parts:
- The 2-dimensional terrain height map representation in the top-down 2D view.
- The 3-dimensional terrain surface representation in the 3D view.
- The terrain editor dialog.


The (top down) 2D View¶



- Height map 1:1 zoom: Zooms the 2D view so each elevation value of the terrains height data will be rendered as one pixel in the 2D view.
- View color
- Greyscale: Renders the height map in a greyscale gradient from black to white where black represents the lowest elevation and white the highest elevation.
- Rainbow: Renders the height map in a rainbow gradient from blue to red where blue represents the lowest elevation and red the highest elevation.
- Debug: Renders the height map in repeating greyscale gradients from black to white. This mode is useful to make detailed terrain modifications where the spectrum of the other color gradients would be to small to see the differences.
The 3D View¶

The Terrain Editor Dialog¶

- Radius: The radius determines the size of the circular area of effect at the current tool position.
- Hardness: The hardness describes if the changes made in the circular area of effect should smoothly blend into the surrounding or have a hard edge at the border of the area of effect.
- Tool effect: The tool effect has different meanings for different sub tools, but can usually be pictured as the intensity with which the tool is used.
- Resolution: The resolution of the terrain height data (elevation values). This has nothing to do with terrains size. The size is determined by the terrains bounding box (which can be scaled like every other brush with The Selection Tool). The resolution determines the number of height values that build up the terrains surface. A higher value usually means that a terrain surface is smoother and more detailed.
- Import: You can import the terrains height data from various file formats including greyscale images in BMP, JPG, PNG and PGM format as well as Terragen files.
- Export: Exporting the terrain into a greyscale image (same formats as stated above) or Terragen file is possible as well.
Terrain Generation¶
If you have created a new empty terrain and you haven’t got
any height data at hand to create its surface, it is often desirable to
automatically generate a basic terrain.
The terrain generation dialog allows for this. By specifying a set of input parameters it lets you create different base terrains and shows the result in real time in a preview window.
- Frequency: A high frequency results in a bumpy surface with many hills and valleys whereas a low frequency will create fewer broader hills and valleys.
- Lacunarity: A multiplier that determines how quickly the frequency increases for each successive octave in the Perlin-noise function. The frequency of each successive octave is equal to the product of the previous octave’s frequency and the lacunarity value.
- Octaves: A higher value adds structural detail to the terrain to the terrain so its surface becomes more natural.
- Persistence: A high value increases the surface contrast which results in steeper slopes between hills and valleys.
- Seed: Determines the random arrangement of hills and valleys for a terrain. You can play with this value to get different results that have all the same characteristics defined by the other parameters above. Note that the resulting terrain from a seed will always be the same (modified by the other parameters of course), so you can always recreate the same terrain again by using the same seed.
You can also find very good and more technical descriptions of these parameters in the libnoise glossary.
The Terrain Editor Sub Tools¶
Tip: While working on your terrain you can undo/redo each step you made
by either using
The Edit Menu or
the undo/redo shortcuts CTRL-Y
and CTRL-Z
. This allows you to
easily try something with the terrain and undo it if the results are not
what you expected.
The Raise Tool¶
The Lower Tool¶
The Flatten Tool¶
ALT
key and then clicking on the position
from which you want to pick up the height value (this works regardless
of the activated sub tool).The Fill Tool¶
The Ablate Tool¶
The Blur Tool¶
The Sharpen Tool¶
The Noise Tool¶
The Road Tool¶
RETURN
key and
the road is constructed. You can also undo road points by clicking the
middle mouse button or pressing the BACK
key.Creating textures for a terrain¶
Keyboard shortcuts¶
SHIFT+F
:- Activates the Terrain Editor tool.
ALT
:- Activates the Eyedropper mode that lets the user pick up a reference height value.
ENTER
:- If the Road sub tool is active a road is constructed from the available road reference points.
BACK
:- Removes the last set road reference point.
The Clipping Tool¶
The clipping tool allows you to cut brushes into 2 pieces along a defined clipping plane. You can keep either one of the pieces or both after cutting them.
Although you could use The Edit Vertices (Morph) Tool to shape a brush, it is sometimes easier to cut off pieces from a larger brush to get the fitting result.
To activate the Clipping tool, click on the related icon in the tool bar
or use SHIFT
+X
.
Using the Clipping tool¶
First you need to have an object already selected by The Selection Tool.
Now you can drag a line between to points in a 2D view to define a clipping plane. The cyan colored line is your clipping plane and shows where the brush is cut. Thick white lines show the parts of the brush that will be kept after the cut. If the whole brush is painted in white lines, the brush will be cut, but both pieces will be kept.
Note that you can’t temporarily deactivate the grid snap setting by
pressing ALT
here, so you have to deactivate it permanently by
pressing SHIFT
+W
if you want to make finer cuts. You can
activate it again by pressing SHIFT
+W
after your finished.
You can switch between the pieces to keep by clicking on the Clip tool
icon in the tool bar or by pressing SHIFT
+X
.
To do the cut you have to press ENTER
and only the chosen pieces
remain.
Clipping tool keyboard shortcuts¶
SHIFT
+X
- Activate Clipping tool.
- If activated → cycle trough clipping modes.
ESC
- Switch back to Selection tool.
The Edit Vertices (Morph) Tool¶
The “Edit Vertices” tool (also called the “Morph” tool) allows
you to edit the individual vertices of a brush and the control vertices
of a bezier patch. (Please refer to
The New Brush Tool and
The New Bezier Patch Tool in order to
learn more about how brushes and bezier patches are created.)
The vertices are the corner points of brushes. Being able to spatially manipulate them indiviually allows you to shape brushes in arbitrary ways that are difficult if not impossible to achieve with the other tools. Also the shape of bezier patches is controlled by special vertices that are called the control vertices of the patch. Modifying these control vertices indirectly modifies the shape of the bezier patch, so that they can be brought into every possible form.
Overview¶
Select the object (brush or bezier patch) whose vertices you want to edit with the Selection tool first. You can also select multiple objects for vertex editing at the same time, but it’s not recommended.
Activate the Edit Vertices (Morph) tool by clicking on the related button on the Tools toolbar or by pressing the
SHIFT+V
shortcut key.Use the mouse to select or drag the vertex or edge handles. The vertex handles are shown as white squares, the edge handles as yellow squares. When you left-click to select individual handles, note that you can use the
CTRL
key in order to “toggle” the selection. (This works very much as with files in the Windows Explorer.) Selection and dragging works both in the 2D as well as the 3D views.When done, just leave the Morph tool e.g. by switching back to the Selection tool. CaWE will then render the resulting brush as usual.
The Convex-Hull Principle¶
For the purpose of editing brushes, the CaWE Edit Vertices tool is implemented according to the “convex-hull principle”. Roughly said, a convex-hull is the smallest space that contains a set of vertices. For a more thorough but mathematical definition please see the Wikipedia article here.
However, most CaWE users are already familiar with convex-hulls from another aspect of mapping, because they occur in a broader context: brushes! Each and every (valid) brush that you create with the New Brush tool is a convex hull of its vertices, and it stays that way no matter how you scale, rotate, shear, clip or morph it later.
Therefore, the morph tool operates by switching back and forth between the normal representation of a brush as you are used to, and it’s convex hull representation. When you activate the Morph tool, the selected brush is first converted into its convex hull representation. Then, when you drag its vertices, you are actually dragging the vertices of the convex hull, and when you’re done, the convex hull is just converted back into the normal brush representation. This works so well because brushes are per definition just another representation of the vertices of a convex hull – switching back and forth is mathematically a straightforward operation.
As a consequence, while it is impossible to use any of the other CaWE tools to turn a valid brush into an “invalid” brush (whatever that is), this statement also holds for the CaWE Morph tool! That is, it is quasi impossible to turn a valid brush into an invalid brush by dragging a vertex or edge handle1). This property makes CaWE different from map editors of other engines (e.g. the Valve Hammer Editor 4.0), where it is really easy to accidentally turn a valid into an invalid brush (which means lost work) with the Morph tool.
In summary, the convex-hull principle that is implemented in the CaWE Morph tool is a very powerful concept that makes vertex editing very simple and intuitive, and at the same time guarantees that you cannot accidentally make an invalid brush. Just try the CaWE Morph tool out for a while – and you won’t go back to other map editors! 😉
The Tool Options Bar¶
When you activate the tool, the tool options bar shows controls
that are specific to the Morph tool:
At the Edit
radio buttons you can choose whether you would like to
edit only the vertices (represented by white handles), only the edges
(yellow handles), or both. Usually it’s the easiest to leave the setting
at both, but if you have a preference you can set it here. Note that
only brushes have edges, the concept does not apply to bezier patches.
The Insert Vertices
button inserts a new vertex into the center of a
selected brush. It does only work if you have exactly one brush
selected. That is, if you have instead a bezier patch patch selected or
more than one brush or even a mix of multiple objects, it will just do
nothing except for presenting you a message box that explains the
exactly-one-brush requirement.
The inserted vertex will initially be located in the center of the brush. Thus, according to the convex-hull principle, it will be “loose” and initially not affect the shape of the brush. However, when you start to drag this vertex so that it becomes relevant for the convex hull, CaWE will automatically create the new shape of the brush according to the convex-hull principle.
The next section has a series of images that demonstrate how you use the
Insert Vertices
button at the example of a cube that gets two
vertices added to form a more complex brush.
Face Splitting and Removal¶
Insert Vertex
button and then dragging
the newly inserted vertex. In the second and fifth image, the new
vertices that were inserted by a click on the Insert Vertex
button
have been selected (red squares) for better visual accentuation. The
respectively next images (the third and sixth) show the result of
these vertices being dragged into new positions.Faces are removed again my dragging one or more of their related vertices back “into” (somewhere near the center) of the brush or just onto other vertices. According to the convex hull principle, they then cannot contribute to the convex hull and thus the brush any more – the face has been removed. (Just read the above image sequence in reverse to see how this works.)
Note that for brushes, the Morph tool automatically eliminates duplicate
vertices. That is, if you drag one vertex exactly onto another so that
you cannot tell them apart any more, CaWE will just remove the duplicate
vertex. This is also why pressing the Insert Vertices
button does
apparently nothing when it is pressed several times in a row: It just
creates vertices all in the same place (the exact center of the brush),
which are immediately collected again because they are duplicates of
each other.
For bezier patches, being able to have multiple individual vertices all in the same place is sometimes a crucial feature, so the removal of duplicates does not apply.
Shaping Bezier Patches¶
When you use the Morph tool to edit the control vertices of bezier patches, the concepts of edges, convex hulls, vertex insertions and duplicate removals do not apply, but otherwise the tool behaves naturally and analogously to editing the corner vertices of brushes.
Selecting vertices individually¶
With bezier patches, it frequently occurs that multiple vertices are in the exact same position, overlaying each other. This is often intentionally and required to achieve certain spatial shapes. When you click on such vertices in the 2D views, they all get selected at the same time. This is usually what is wanted, but if instead you want to selected the vertices separately, just clear the selection and then click on the vertex in the 3D view. Contrary to the 2D views, selecting vertices in the 3D view only ever selects one vertex at a time. Although the situation looks visually the same as before in the 2D views, you can now use the mouse to drag the single vertex in the 2D or 3D views without affecting the others in the same place.
Selected Topics¶
Groups¶
Groups are a great aid for organizing your map and for making many mapping tasks easier. Map elements that have been put into a group can be treated as a whole, and thus they can be edited, transformed and modified as if they were a single object. Groups can also hide their elements from the views and lock them in order to prevent them from being edited.
In the latest versions of CaWE, groups are also persistent: Groups are saved in and loaded from Cafu map files so that they are available from one session to the next. Moreover, any changes to groups and their properties are recorded in the edit history and can be undone via the Edit → Undo menu.
In summary, groups act like layers in image processing programs. They are helpful and easy to use. This section explains the details.
Creating Groups¶
In order to create a group, use the Selection tool in order to select the map elements that you want to become the members of the new group. Then use one of the following methods in order to put the selected elements into a new group:
- Use the Tools → Group (Ctrl+G) menu.
- Click one of the buttons Group, Hide, or Hide Other in the Selection tool toolbar.
Each of these menu items or buttons creates a new group and puts the selected map elements into it. The Hide Other button is an exception, as it will group everything else. The two Hide buttons additionally mark the newly created group as hidden, so that the selected map objects will disappear from the views.
The Groups Panel¶
The Groups panel shows a list of all groups in the
map. If the Groups panel is currently not visible, use the View →
Panels → Groups menu to show it.
Each group is shown in a line with information about the groups settings: its visible/hidden status, its name, its color, its edit/locked status, and whether the group members are selected individually or as a whole. Each of the icons can be clicked in order to toggle its status.
Group Visibility¶


Group Name and Color¶
The initial name of a group is automatically assigned when the group is first created, and can be changed at any time: Press F2, single-click a selected group, or use the context menu (described below) in order to assign a new name, e.g. one that describes the content or purpose of the group.
When you double-click the group name, the members of the group are selected in the map.
The groups color is indicated by the background color of the group name. When activated in the CaWE Options dialog, the member elements of a group are rendered in the groups color, so that they are easy to see in the map views.
Locking Groups¶


Group Selection¶


Editing groups¶
Groups can be edited via the Groups panels
context menu: Right-click into the Group panel in order to open its
context menu:
- Select
- Selects all members of the group in the map, just as if they had been selected with the Selection tool. This is the same as a double-click on the group name.
- Edit
- Using the submenu, you can change the properties of one or more groups that are selected in the Groups panel.
- Dissolve
- This menu item ungroups the members of the group and then deletes the group. Note that it does not delete the map elements itself, they’re just ungrouped.
- Merge groups
- When two or more groups are selected, their members can be merged into a single group.
- Move up/down
- Use these menu items to change the order of the groups in the list.
It is important to note that multiple groups can be edited via the context menu: Just select one or more groups, and the context menu operation will affect them all at once.
Any changes to groups and their properties are recorded in the edit history and can be undone via the Edit → Undo menu.
Dealing with Leaks¶
This section explains what a leak is, why leaks are important, how they are found and fixed, and how leaks are prevented.
What is a Leak?¶
Maps created for the Cafu engine are preprocessed by several compile tools (e.g. CaBSP, CaPVS, CaLight) for optimal performance. These compile tools assume that any map has an inside (where the player and monsters are), and an outside that nobody except for the mapper will ever see. The inside must be sealed “air-tight” or “water-tight” from the outside.
That is, if you imagine you flood-filled the map from the inside with water or pressurized air, at no point must the water or air be able to escape to the outside. Therefore, each place where that would be possible is called a leak.
“A leak is a hole in the world, where the inside of it is exposed to the (unwanted) outside region.” – CaBSP error message when a leak was found.
Examples for Leaks¶
Gaps in the geometry¶
The example to the right shows a leak that is caused by an obvious gap in the geometry that leads to the void (the outer region). This is the classical example and most common type of leaks, and such leaks are usually easy to find and fix.
Inappropriate materials on outside walls¶
Materials that are see-through (like the grate in the center of the image) or translucent (like the glass pane to the right) cannot be used on outside walls as is this example, because such materials obviously don’t seal the map.
To fix the problem, you either have to replace such materials with other materials that are solid, or make another room that has solid walls on the other side of (“behind”) these surfaces.
Note that contrary to the materials shown in this example, skydome materials do seal the map.
bspPortals
clip flag set in their material definition
seal the map, all others don’t. Future versions of CaWE will directly
indicate the status of this flag in the Material Browser, but
currently you have to look-up the definition of a material in its
.cmat
file to find out the status of this flag. Good news though
is that most materials behave totally naturally:Terrains, Bezier Patches and Entities¶
Terrain and Bezier Patch primites never seal the map, even if their material is solid. Therefore, if you dragged the terrain in this example to cover the entire floor, you still cannot expect it to prevent the map from leaking.
The same is true for brush entities, i.e. entities that are made from
brushes. For example, if you make a func_wall
or func_door
entity and place it so that it appears to contribute to the outside
wall, CaBSP will still report a leak, because only the global “world”
brushes are taken into account for the sealing hull.
As shown in the image, the proper solution is to use the
Textures/meta/caulk
and other materials like walls and skies to make
a “containing room” around such primitives and entities. The
Textures/meta/caulk
material is especially useful in such cases
because it seals the map but doesn’t render (is invisible) in the engine
later.
TechDemo.cmap
for a properly sealed terrain example.Leaks due to bad brushes¶
Sometimes leaks can also be caused by bad brushes like the one shown in this example (click image to enlarge). Such leaks are the most problematic: They are very hard to see visually, and they can get CaBSP thoroughly confused1). Even worse, usually not much helps but deleting the offending brush, and make it anew with the New Brush and other tools.
Effects of a Leak¶
If your map has a leak, the CaBSP compiler will automatically detect it and consequently abort the compilation with an error message like this (if there is more than one leak in the map, only the first leak will be reported):
*** Fill Inside *** 0: 0: 1
### LEAK DETECTED! ###
A leak is a hole in the world, where the inside of it is exposed to the
(unwanted) outside region. Thus, a leak pointfile has been generated.
Load this file into the world editor CaWE, and find the beginning of the line.
Hint: The beginning is always near one of the "info_player_start" entities.
Then find and fix the leak by tracing the line until you reach the outside.
(The line always takes the shortest path, so this should be easy.)
Notes:
- Leaks can be *very* small. Use a close-up view, if necessary.
- Use the grid. The grid is useful to fix leaks + to avoid them from the start.
- Make sure that *all* "info_player_start" entities are inside the world!
- Be aware that both the clip hull and the draw hull must be sealed.
- Please refer to the documentation for additional information.
Pointfile written to Games\DeathMatch\Maps\LeakDemo.pts
FATAL ERROR: Stopped by leak.
Program aborted.
That means that with a leak in the map, you cannot run the map at all. As CaBSP doesn’t write any output file in this case (except for the above mentioned pointfile), neither the subsequent compilers (CaPVS and CaLight), nor the Cafu engine itself can run the map.
Future versions of CaBSP may reduce the severity level of the occurrence of a leak from an error to a mere warning. This will allow you to run your map with Cafu even if it has leaks, but nonetheless will leaks remain a problem that should be fixed. Leaks always indicate that the map could not be optimally processed, and thus imply higher polygon counts and lower performance.
The next section will tell you how to find the leaks reported by CaBSP in the map.
Locating Leaks in the Map¶
Finding leaks is very easy: When CaBSP reports that it found a leak (see
example error message and description above), it also creates a
corresponding pointfile. A pointfile is an auxiliary file that
contains the description of a trail from one of the
info_player_start
entities to the outside. The leak is always
located somewhere along that path.

Use the 2D views and especially the 3D camera view (see
2D and 3D Views for details) to follow the trail
from the starting point near one of the info_player_start
entities
to the place where the line leaves the inside of the map and escapes to
the outside. Fix the so found leak however seems appropriate.
You may notice that loading the pointfile can decrease the rendering performance in CaWE, especially if the trail is very long. Therefore, once you’ve found the leak, you can unload the pointfile again by selecting the Map → Unload Pointfile menu item.
Finally, restart the compilation (CaBSP) to check if the map is now completely sealed or if there are more leaks.
Preventing Leaks¶
The best way to deal with leaks is to prevent them right from the start. Here is a list of suggestions and considerations in this regard:
- Use the grid (Map → Show grid) and turn on grid snapping (Map → Snap to grid). The grid and grid snapping are your most powerful allies when it comes to see and avoid leaks while you’re constructing your map.
- Run the Map → Check for Problems menu item occassionally and before compiling your map.
- Avoid all tools that potentially introduce rounding errors and thus misaligned brushes. As a gross guideline, all tools that operate on the grid and that are supposed to produce results on the grid are usually safe, such as resizing rectangular blocks, shearing, vertex manipulation, mirroring, clipping and carving. The following operations are sometimes less safe: Arbitrary (any angle) rotation and clipping and carving when the result has vertices that are off-grid. For less-safe operations it is often better to try to mimic the same effect with the safer operations. For example, when you want to carve an arched door into a wall, cutting and placing the wall brushes manually is often better than employing the (more convenient) Tools → Carve tool.
Note that leaks are not (!) prevented or fixed by putting the entire map into a big box, even if the strategy that has been suggested above for working properly with terrains might make you think so. Although putting everything into a big box will make CaBSP compile the map successfully and thus seemingly fix the leak, the problems associated with a leak (e.g. high polygon count and bad performance) will persist. This is not a solution.
Conclusion¶
Being able to load the CaBSP-generated pointfiles directly into CaWE makes finding and fixing leaks relatively easy. However, one of the most important aspects about fixing leaks is to prevent them right from the start.
Working carefully and making sure that brushes are properly aligned (snapped) to the grid can help significantly with avoiding leaks even before they occur. The cleaner and more organized you build your geometry, the easier will it be for you to not build them accidently into your map in the first place, and when they still occur, the easier they are to locate and fix.
In general, it’s also a good idea to occasionally test-compile your map while it is only partially complete and still a work-in-progress. Besides that this will help you to fine-tune your geometry, it will also point out leaks one at a time, which makes finding and fixing a lot simpler and faster than later when your map is large and fully detailed.
See Also¶
Creating Teleporter Stations¶
This tutorial shows how a network of teleporter stations can be added to a game map: A set of teleporter stations is distributed throughout the map. Each station has a graphical user interface that the player can use to select the station that he wants to teleport to, and to activate the teleportation.
The tutorial involves the placement of new entities into the map, GUI scripting and map scripting. As such, it is also a gentle introduction into Cafu game scripting.
All tasks are demonstrated using the sample map BPWxBeta that is included with Cafu.
Creating the teleporter controls GUI¶
Each teleporter
station is supposed to have a GUI that the player can use to control
which other station he wants to teleport to, and to activate the
teleportation.
We use the GUI editor component of CaWE in order to create the new GUI, an example is shown in the image.
<
and >
buttons should increment or
decrement the number of the station that the player is being
teleported to, and the big button below should actually trigger the
teleportation.Writing custom code for the teleporter controls GUI¶
When the GUI was saved in the GUI editor, it automatically wrote two files:
Teleporter_init.cgui
andTeleporter_main.cgui
The first file contains the actual data that the GUI editor loads and saves, the second file is for your hand-made customizations. In short, note that the first file is overwritten whenever the GUI editor saves a GUI file, whereas the second file is only created once as an empty stub file. The GUI editor touches the second file never again, so that you can use it for hand-written customizations.
We now edit file Teleporter_main.cgui
and enter the following script
code:
dofile("Games/DeathMatch/GUIs/Teleporter_init.cgui");
function ButtonMinus:OnMouseEnter()
self:set("borderColor", 1.0, 0.0, 0.0, 1.0);
self:interpolate("textScale", 2.2, 2.4, 500);
end
function ButtonMinus:OnMouseLeave()
self:set("borderColor", 0, 0.333333, 0.490196, 0.5);
self:interpolate("textScale", 2.4, 2.2, 500);
end
function ButtonMinus:OnMouseButtonUp()
local NodeNr=tonumber(DestNode:get("text"));
if (NodeNr>1) then
DestNode:set("text", NodeNr-1);
end
return true;
end
function ButtonPlus:OnMouseEnter()
self:set("borderColor", 1.0, 0.0, 0.0, 1.0);
self:interpolate("textScale", 2.2, 2.4, 500);
end
function ButtonPlus:OnMouseLeave()
self:set("borderColor", 0, 0.333333, 0.490196, 0.5);
self:interpolate("textScale", 2.4, 2.2, 500);
end
function ButtonPlus:OnMouseButtonUp()
local NodeNr=tonumber(DestNode:get("text"));
if (NodeNr<MAX_NODES) then
DestNode:set("text", NodeNr+1);
end
return true;
end
function ButtonGo:OnMouseEnter()
self:set("borderColor", 1.0, 0.0, 0.0, 1.0);
self:interpolate("textScale", 0.5, 0.52, 500);
end
function ButtonGo:OnMouseLeave()
self:set("borderColor", 0, 0.333333, 0.490196, 0.498039);
self:interpolate("textScale", 0.52, 0.5, 500);
end
function ButtonGo:OnMouseButtonUp()
local origNr=OUR_NODE_NR;
local destNr=DestNode:get("text");
game.runMapCmd("teleport(" .. origNr .. ", " .. destNr .. ");");
return true;
end
-- This function is called as soon as the entity related to this GUI has been initialized.
-- Note that our entities must have names like "teleporter_2_of_5" for this to work.
function OnEntityInit()
-- Figure out the total size of the teleportation network (number of nodes)
-- that this station is in, and which number this node/station has.
OUR_NODE_NR, MAX_NODES=string.match(gui:getEntityName(), "(%d+)_of_(%d+)");
OUR_NODE_NR=tonumber(OUR_NODE_NR) or 1;
MAX_NODES =tonumber(MAX_NODES) or 3;
InfoStation:set("text", "Station " .. OUR_NODE_NR);
DestNode:set("text", (OUR_NODE_NR % MAX_NODES)+1);
end
The first line of the script loads and runs the previously mentioned first file, that initializes the basics of the GUI. As such, the first line is crucial because it is responsibe for “connecting” both files.
After the GUI script is fully loaded, the Cafu Engine initializes the GUI by
- first calling all
OnInit()
methods of all windows (they are defined inTeleporter_init.cgui
), - then calling all
OnInit2()
methods of each window (of which we have none at all, but if we had, they were inTeleporter_main.cgui
), - and finally calling function
OnEntityInit()
for 3D in-game GUIs such as ours.
The OnEntityInit()
method is very important as is determines the
number of this teleporter station (or “node”) and the total number of
nodes, and saves both values in global variables for future use. It also
updates the “Station XY” text of the InfoStation
window that
indicates to the player at which station he is currently standing, and
sets a reasonable default for the destination station that we’re
teleporting to.
All other methods are event handlers that the Cafu engine calls whenever
the related event occurs. The OnMouseEnter()
and OnMouseLeave()
methods are only used for adding some visual eye candy, and so we won’t
further discuss them.
The most interesting method is ButtonGo:OnMouseButtonUp()
, that is
called when the player presses the button that is supposed to activate
the teleporter. However, note that this GUI script is like implementing
the control software that runs on the teleporter station, just like a
desktop program that would run on the station if the teleporter was
real. As such, the GUI cannot implement the teleportation itself, but it
must ask the map script to do it.
The GUI can use the runMapCmd()
function of the game
object in
order to ask the game script to do something. We will later write a game
script function teleport(origNr, destNr)
that does precisely that:
Teleport a player from station origNr
to station destNr
, and
thus when the player presses the button, we have this function called
here.
Placing teleporter stations in the game map¶
The next task is
quite simple: We place the new teleporters into the map. To do so, use
the New Entity tool in order to create two
new entities whereever you want to have a teleporter station:
- One
static_detail_model
that shows the big screen with the controls GUI, and - one
info_generic
entity that indicates the source and destination point of the teleportation.
Note that you must name the static_detail_model
with a name of the
form somename_X_of_Y
, where X is the number of this station and Y is
the total number of the stations. This is because our GUI script above
has been written to figure out these numbers from the name of the
entity.
Implementing teleport() in the map script¶
The final task is to write the above mentioned teleport()
function
in the map script: For the BPWxBeta example map, we create or open
Games/DeathMatch/Worlds/BPWxBeta.lua
, and enter the following code:
-- It's more readable to call wait(x) rather than coroutine.yield(x).
wait=coroutine.yield;
-- This function reloads and runs this script again.
-- Useful for working with and testing the script "online",
-- i.e. while the engine is running and without reloading the map!
function reloadscript()
dofile("Games/DeathMatch/Worlds/BPWxBeta.lua");
end
-- This function is called by the teleporter GUI script when the user wants to teleport.
-- origNr and destNr are numbers like 1 or 5 that indicate from and to which node in the
-- teleportation network the teleportation should occur.
--
-- TODO/FIXME: It would be nice if we could learn from an additional parameter which
-- (player) entity was actually operating the teleporter controls (i.e. who pressed
-- the "Go" button on the related GUI).
function teleport(origNr, destNr)
-- Prevent re-entrancy in the case that this method is called very quickly in succession.
-- This can happen with the current EntHumanPlayerT code, which is sort of a bug.
if (isTeleporting) then return true end
local ox, oy, oz=_G["info_generic_" .. origNr]:GetOrigin();
local dx, dy, dz=_G["info_generic_" .. destNr]:GetOrigin();
Console.Print("Teleporting from node " .. origNr .. " to node " .. destNr .. ", ");
Console.Print("which is at coordinate (" .. dx .. ", " .. dy .. ", " .. dz .. ").\n");
-- Teleport all entities with name "Player*" to the destination node.
for PlayerNr=1, 99 do
local PlayerEnt=_G["Player" .. PlayerNr];
if not PlayerEnt then break end
local px, py, pz=PlayerEnt:GetOrigin();
local ax=px-ox;
local ay=py-oy;
local az=pz-oz;
if (pz>oz and math.sqrt(ax*ax + ay*ay + az*az) < 2000.0) then
-- VARIANT 1:
-- When teleporting PlayerEnt to (dx+ax, dy+ay, dz+az), it is safe to teleport
-- multiple players all at the same time (continuing the loop), as their
-- relative positioning doesn't change.
-- However, depending on the map geometry, teleporting to (dx+ax, dy+ay, dz+az)
-- could teleport the player into solid matter, as it requires that at the dest
-- there is as much free space (in the same absolute direction) as at the origin.
-- PlayerEnt:SetOrigin(dx+ax, dy+ay, dz+az);
-- VARIANT 2:
-- When teleporting PlayerEnt to (dx, dy, dz+az), the results are much easier
-- to foresee, but this requires teleporting only one player at a time.
PlayerEnt:SetOrigin(dx, dy, dz+az);
break;
-- TODO/FIXME: We should check that the destination space is actually free
-- from other players and entities before we relocate PlayerEnt there!
end
end
isTeleporting=true;
wait(0.5);
isTeleporting=false;
end
About Lights and Shadows¶
(FIXME!) This page is still under construction (!)
One of the key questions that mappers frequently raise is how to define and place light sources. While placing light sources is generally easy, this section explains the types of available lighting techniques in Cafu and the options to create light sources for each.
The Cafu engine implements two different types of lighting techniques:
- Radiosity-based lighting and
- dynamic lighting.
The two lighting techniques are quite distinct from each other, and each comes with a set of feature of its own. Nonetheless, both techniques peacefully coexist in the Cafu engine and mappers frequently employ both in a single map.
Radiosity-based Lighting¶
One of the most fundamental lighting techniques in computer graphics is the Radiosity method. Radiosity methods compute lighting based on a physical model, and it is the nature of the underlying mathematics that characterizes the features of the technique.
The big downside of Radiosity is that it requires a preprocessing step. This preprocessing step can be computationally very expensive and thus take a long time to complete. It is implemented in a special tool called “CaLight”, which is one of the map compilers that are covered in sections Compiling Maps for Cafu and Compiling Maps at the Command-Line.
The fact that Radiosity is slow to precompute also means that it cannot work with dynamic objects: Radiosity takes walls and any other static object into account, but anything that moves will not influence the Radiosity-based lighting result.
Good news about Radiosity-based lighting is that once the preprocessing step it complete, it is fast. Independently of the number of light sources or complexity of the scene, Radiosity-based lighting provides very good performance at run-time during the game. It is therefore a natural choice for large-scale base lighting of any level.
Even better, Radiosity lighting results looks stunningly good. No matter what hardware vendors tell you about their latest products, no matter what game developers tell you about dynamic lighting (as I do, too; see below), none of these techniques can beat the realism of lighting generated by Radiosity methods. Based on an accurate physical model, the natural propagation and appearance of lights and shadows is unique to Radiosity methods.
The Radiosity method also handles area light sources without special measures, but as a natural part of the algorithm. Area light sources are an important key feature, because they are the main contributors to a realistic lights and shadows distribution with diffuse reflections and soft shadows. This is contrary to dynamic lighting, where lights are only points in space, soft shadows are always the result of some kind of trick, diffuse reflections are not possible at all, and a physical model is never involved.
For these reasons, Radiosity was the first lighting technique implemented in Cafu.
Here is an overview of the available Radiosity light sources and how they are created in a map:
Area Light Sources¶
Any primitive (brush or Bezier patch) surface that you place in a Cafu map can be turned into an area light source. The key point here is that a surfaces characteristic of being an area light source is not (!) directly set in the Cafu World Editor CaWE. Rather, being an area light source is a material property. That means that a surface becomes an area light source when it has a material applied to it which in turn is defined to emit Radiosity light.
- In order to place an area light source, use the Edit Surfaces tool to apply an appropriately defined material to the desired brush or Bezier patch surface. You can learn which materials cast Radiosity area light by clicking on them once in the Material Browser. The bar at the bottom will show “Radiant Exitance” information on the selected material, if any. Tip: Filter for materials with the string “light” in their name. This heightens the chance to find a relevant material quickly.
- In order to change the definition of a new or existing material to
emit light, make sure that the
meta_radiantExitance
keyword is employed. Please refer to the Material Systems Keyword Reference for more details. Note that the effect of changing the definition of an existing material is global. That is, if the material is used elsewhere (in another map), also the other map will be affected when CaLight is run next.
Point light sources¶
You can also place point light sources to participate in the Radiosity lighting process. This is easily achieved with the New Light tool, whose documentation explains the placement and parameter setup in detail.
Sky Light¶
Adding sun- or moonlight to a map works analogously to adding an area light source: Just apply a “sky” material to any surface, and if the material is defined to emit skylight, everything else will happen automatically:
- The Material Browser browser informs you whenever a material with “Irradiance” values is selected.
- The material definition can be changed according to the Material
Systems Keyword Reference, see the
meta_sunlight
keyword. - You may refer to the Your First Map tutorial to see an example. It’s actually that easy!
Dynamic Lighting¶
Dynamic lighting has become popular with the advent of hardware-acceleration for 3D graphics in the recent years. It is the preferred and most frequently employed lighting technique in most recent commercial graphics software.
The essential characteristic of dynamic lighting is that its computational steps occur per-pixel and per-frame. Per-pixel means that the lighting computations occur on the basis of the output pixels of the rendered primitives (triangles). Per-frame refers to the fact that all lighting computations occur only at runtime, and in fact, they are performed for each rendered frame anew. This allows both light sources and lit objects to move arbitrarily through the scene, with the lights and shadows being updated correctly and instantaneously.
These properties have many implications for the practical use of dynamic lighting: Dynamic lighting is fast, flexible, dynamic, instantaneous, yields good results and is well supported and accelerated in hardware.
Even though dynamic lighting looks not quite as real as the Radiosity method, this is often not a problem, because lighting that looks dramatically good is often preferred over the “boring natural”. Moreover, dynamic lighting avoids the computational complexity that comes with the Radiosity method. Therefore, dynamic lighting is an important component in Cafu.
Point light sources¶
Projective lights¶
Stencil shadows¶
Shadow-Map shadows¶
Spherical Harmonics Lighting¶
Lighting with Spherical Harmonics (“SHL”) is an area of active research in computer science. Its goal is to combine the merits of Radiosity-based lighting with light sources that can move, especially when the light sources are very far away from the scene, like for example the sun or the moon.
SHL has been implemented in the scope of my diploma thesis in the Cafu engine, but is currently not supported by the public releases. You may refer to the thesis linked below for more information.
See Also¶
- Methods for Real-Time Lighting – Diploma (Masters) Thesis by Carsten Fuchs.
Importing Maps from other Games/Editors¶
If you have already made maps with other editors for games like Half-Life 1, Half-Life 2, Quake 3 or Doom 3, you possibly wish to use them with CaWE and Cafu as well. For this purpose, several importers are provided that can load such maps directly into CaWE.
In order to import a foreign map, just activate the File → Open…
menu item or press CTRL+O in order to open the file open dialog.
The drop-down box near the bottom presents a list of all file types that CaWE can directly load or import. Just choose the desired file type and proceed to open a map file of that type as usual.
After the import, there are normally two additional problems that you may encounter: material and entity mismatches.
Material mismatches are caused by the fact that the material systems of all game engines are different from each other. While we can create new materials in Cafu under the same names as those that occur in the imported map, converting the used textures and other material details is generally not feasible. Some importers therefore substitute all material occurrences in the imported map file with native Cafu materials that are valid, but have different names.
In all cases, you’ll have to re-texture the imported map manually with native CaWE materials. This is recommended and frequently desired for best results anyway. Employing the powerful Edit Surfaces tool and the Replace Materials dialog gets the job quickly and conveniently done. Making use of the “Only show USED materials” checkbox in the Material Browser is also helpful.
The following list summarizes what you have to know and consider about entity mismatches:
- Because the existing entities in your world were defined and made for
another game, they will mismatch with the Cafu MOD entity
definitions! Note that there are two kinds of mismatch:
- Some entities exist both in the other game as well as Cafu (for example translucent brushes, ladders, …), but their names and/or their properties differ.
- Other entities only exist in the other game and Cafu has no equivalent entity at all, or vice versa! For example, Cafu DeathMatch has different weapons, but unfortunately lacks of many of the advanced entities of other games. I am very sorry, but at present you have to find some kind of work-around in such cases. However, I am doing my best to improve the situation in the future.
- Here are some suggestions to fix the entity mismatchings:
- It’s probably the safest (easiest, but most expensive) to simply delete all existing entities from your world, and only keep the geometry. Then, recreate them from the Cafu (DeathMatch) entities.
- In many cases it might be preferable to simply open the Properties dialog for each entity, and to reset their properties there. Just make sure that you actually check out each individual property tag.
- If you are very experienced, you might solve many mismatchings
directly by loading the
map
file into a text editor.
- Although Cafu ignores unknown entities (e.g. entities left from other
games), and fills-in default values for unknown properties, it is
still best to do the conversion carefully in order to avoid
unexpected results. For example, be specially careful with
func_wall
entities: you’ll have to reset their rendermode properties (translucent, blue becomes invisible, …) explicitly!
The goal of this tutorial is to show some methods creating a sky or an evironment for your scene.
Method One: Creating a skybox¶
First, create a new empty map by clicking “File”, then “New” in the menubar. Alternatively, you can open an existing map, to which you want to add a skybox.
Create a block. For this, click the “New Brush” Icon in the left toolbar. In the appearing green bar at the top of the main-window check if “block” is selected as “New brush shape”. In the orthogonal windows (those with the front view, left view, down view), draw a cube. Make it’s dimensions bigger than your scene shall be, so that it surrounds the entire scene. Also, be sure that the size of height, width and depht is the same. Press enter. Don’t worry, if the size is not really exact now, you can simply correct it later.
Next, choose your texture for your sky-map. You can select a texture from the skydome-folder in the textures-directory coming with your Cafu SDK, or you can make your own skybox, textures. How this can be done, I will explain later in another tutorial.
To select your sky-texture, press the “Browse”-Button, which is located under the Texture-Preview-Window. A new window opens, showing all texures the CaWe can find in it’s pathes. In the filter input box, at the bottom of this window, type sky, so that only the textures related to this word are shown.
For example, select the “PK_Autumn”-Texture, by double-clicking it. The window will close, and the selected texture will be shown in the preview window. Now, select your cube with the selection tool. For this, click the upper left blue icon in the left toolbar, then click on one face of your cube. The whole cube will be drawn in red color. Alternatively, you can draw a select box around your cube, and it will be highlighted in red too. If you have a map loaded before, be sure that nothing els is selected. In the blue toolbar at the top of the main-window, click “Apply Material”. With your mouse pointer in one of the orthogonal windows, press enter. The sky-texture will be projected on your cube immediately in a perfect way. Don’t worry, if your 3D-window will stayed black. Probably your camera is inside your cube, and you are not able to see it right now. This will change during the simple next, last step.
Again, select your Box with the select tool. Then, in the menu-bar, first click “Tools”, then “Make hollow”.
In the opening window, confirm the entry of 32 units, press “Enter”, and you are done. Your skybox will be shown also in the 3D-Window, and you are ready to compile your map.
Placing Water¶
This tutorial was taken from the New Entity page.

2. In a 2D view, drag out a box the size you want your water to be. Adjust the size in the other 2D views.


4. With your mouse cursor over one of the 2D views, press Enter. The brush should be selected if not, select it with the selection tool.


Now compile your map, and you should see water!
Dialog Reference¶
The Configure CaWE Options Dialog¶
This dialog is opened by selecting Configure CaWE… from The File Menu.
It is used to configure the general appearance and handling of CaWE.
Game Configurations¶
This tab contains configuration options for game configurations. Each map has to use a game configuration in order to work.
Game configurations are automatically created from the subdirectories of /Games that have a game data file (.fgd) with the same name as the directory in it. For example /Games/Deathmatch/Deathmatch.fgd is a valid game configuration with the name Deathmatch.
In this tab you can edit properties for game configurations that will be used when editing a map that uses this game configuration.
- Game Configuration Selection
- Selects the game configuration to adjust its properties.
- Default Point Entity class
- Sets the Point Entity class that is selected by default when a new map is opened/created.
- Default Brush Entity class
- Sets the Brush Entity class that is selected by default when a new map is opened/created.
- Default texture scale
- Sets the default texture scale for this profile.
- Default lightmap scale
- Sets the default lightmap scale for this profile.
- Cordon texture
- This option is not implemented at this time.
General¶
This tab contains general configuration options for the editor to control its behavior. The paths to the executables in this tab are very important so CaWE can find them to compile and run edited maps.
- Undo Levels
- Sets the maximum number of actions performed by the editor that can be revoked.
- Allow grouping/ungrouping while Ignore Groups is checked
- Toggles if you can group or ungroup selected objects even if the Ignore Groups Option from the Selection Tool options bar is checked.
- Stretch arches to fit original bounding rectangle
- This option stretches a arch to fit the bounding rectangle when created. If this options is not selected the size of the arch will be determined by the size of the bounding rectangle as well as the parameters set in the arch creation dialog (see The New Brush Tool).
Executables¶
The path of executables used to compile and run maps can be configured here in case the user changed their paths or wants to use different ones.
- Engine executable
- Sets the path to the Cafu executable.
- CaBSP executable
- Sets the path to the CaBSP executable.
- CaPVS executable
- Sets the path to the CaPVS executable.
- CaLight executable
- Sets the path to the CaLight executable.
At the bottom of this tab, the path to your configuration data is shown.
2D Views¶
This tab holds configuration options that define the appearance of the editors 2D views.
Options¶
- Crosshair cursor
- This option is not implemented at this time.
- Default to 15 degree rotations
- If rotating an object this sets the rotation steps to 15 degree
instead of smooth rotating. Note that you can still rotate objects
smoothly by pressing
SHIFT
while rotating. - Display scrollbars
- Toggles the display of scrollbars in the 2D views.
- Draw vertices
- Toggles display of objects vertices in a 2D view.
- White-on-Black color scheme
- Switches between white grid on black background and black grid on white background modes.
- Keep group when done dragging
- When cloning objects from a VisGroup, this option adds the cloned objects to the same VisGroup after dragging them.
- Center on camera after movement in 3D
- This option is not implemented at this time.
- Use Visgroup colors for object lines
- Toggles if the line color defined in the Edit VisGroups dialog is used to display the objects that belong to this group in a 2D view.
- Arrow keys nudge selected object/vertice
- If activated the arrow keys can be used to move objects or vertices.
- Reorient primitives on creation in the active 2D view
- When creating a brush in a 2D view, this brushes top side is per default oriented in the direction of the top down 2D view. If this option is activated the top side of the brush will be oriented in the direction of the 2D view in which the brush has been created.
- Automatic infinite selection in 2D windows (no ENTER)
- If dragging a selection box, this option determines if the objects in the selection box are selected instantly after the mouse button is released.
- Selection box selects by center handles only
- Determines if the center handle of objects has to lie within a selection box for the object to be selected. Otherwise any object that lies partially in the selection box is selected.
Grid¶
- Size
- Defines the default grid size.
- Intensity
- Adjusts the grids color intensity.
- Highlight every 64 units
- If checked, a grid line is highlighted every 64 units.
- Highlight every 1024 units
- If checked, a grid line is highlighted every 1024 units.
- Highlight every X grid lines
- If a grid line is the X. grid line in a row, it is highlighted.
- Hide grid smaller than 4 pixel
- If the distance between two grid lines gets smaller than 4 pixels in a 2D view, the grid lines are no longer displayed.
- Dotted Grid
- Toggles between a grid with solid lines or dots.
3D Views¶
This tab holds configuration options that define the appearance of the editors 3D view.
Performance¶
- Animate models
- With this option activated, models are animated in the editor.
- Back clipping plane
- Sets the back clipping plane in the editors 3D view. With high values even geometry far away from the camera is rendered. This option has a huge impact on the performance of the editor, especially in big maps.
- Model render distance
- Determines the distance at which models are rendered as bounding boxes instead of the real model meshes.
The Replace Materials Dialog¶
This dialog can be opened by clicking on the related menu item in The Tools Menu or by clicking on the icon in the materials bar (see The Main Window User Interface).
With this dialog you can find a specific material and its related faces and replace this material by another one.
Find¶
- Material field
- Name of the material to search for. Browse opens The Material Browser.
Search in¶
- selected objects
- Searches only in the currently selected objects for faces with the material to find.
- all objects (whole world)
Searches in all map objects.
- inclusive brushes
- Includes brushes into the search.
- inclusive bezier patches
- Includes bezier patches into the search.
- also in hidden visgroups
- Includes invisible objects into the search.
Search for¶
- exact matches
- Only materials that match the exact material name given in the material field are found.
- partial matches
- Materials whose names match the searched material name partially are also found (e.g. search name: wall; partially matches with wall_01, mywall, etc.).
- Find only
- Found faces with the specified material are selected but the material is not replaced.
Replace¶
- Material field
- Name of the material to replace with. Browse opens The Material Browser.
- Replace and rescale
- The replacement material is rescaled in the same way as the old material.
- Replace and not rescale
- The replacement material is applied without rescaling.
The Paste Special Dialog¶
This dialog is opened by clicking on Paste Special… in The Edit Menu. This option is only available if an object has been copied to the clipboard before.
Paste Special allows you to paste more than one copy of a selection into the map. You can for example paste a row of the same object into the map, whereat the object is pasted multiple times and each copy is shifted in position to form a row with the other objects.
- Number of copies to paste
- The number of copies from the objects in the clipboard that will be pasted.
- Start at center of original
- If this is activated, pasting starts at the center of the original object/s. Otherwise it starts at the center of the last two selected 2D views.
- Group copies
- Objects are combined into a group after pasting them.
- Translation (per copy)
- Sets the offset in x/y/z direction of each pasted object. This offset is accumulative, so the offset of an object is its own offset and the sum of the offsets off all previous objects.
- Rotation (per copy)
- Sets the rotation offset of each pasted object. This offset is accumulative, so the offset of an object is its own offset and the sum of the offsets off all previous objects.
The Find Entities Dialog¶
This dialog can be activated using the related item from The Edit Menu.
It is used to find entities by a given name.
Enter the name of the entity you want to find in the name
field.
By pressing OK a search is started and the found entities will be selected on the map.
The Object Properties Dialog¶
This dialog is obsolete since CaWE release 8.02 (February 2008). If you employ CaWE version 8.02 or newer, please refer to the new Entity Inspector dialog instead. The new Entity Inspector dialog subsumes all functionality of the Object Properties dialog.
This dialog will be revised and documented later.
The Goto Brush/Entity Dialog¶
This dialog can be accessed by clicking on the related item in The Map Menu.
If you got an invalid brush or entity on your map, the compiler will tell you the number of the according brush/entity, so you can select it with this tool and it will be marked and centered in the views.
- Entity Number
- Enter the number of the brush you want to find here.
- Brush Number
- Enter the number of the entity you want to find here.
- Search visible brushes only
- Toggles if only visible brushes/entities are considered in the search.
The Entity Report Dialog¶
This dialog is obsolete since CaWE release 8.02 (February 2008). If you employ CaWE version 8.02 or newer, please refer to the new Entity Inspector dialog instead. The new Entity Inspector dialog subsumes all functionality of this Entity Report.
This dialog is accessed by clicking on the related item in the The Map Menu.
It shows a list of all entities in this map, that is filterable with different filter options.
- Entity list
- A list of all entities in this map, filtered by the given filter options below.
- Mark
- Marks the currently selected entity in the list on the map.
- Go to
- Centers the views onto the selected entity from the list.
- Delete
- Deletes the selected entity from the list and the map.
- Properties
- Opens the Properties Dialog for this entity.
- Filter
Filter settings.
- Brush Entities
- Show brush entities in list.
- Point Entities
- Show point entities in list.
- Include hidden Entities
- Show hidden entities in list.
- By Key/Value
- Filter the list by a specific key/value pattern in the entity properties.
- Exact
- Toggles if the key/value pattern has to be exact the same or if a partial match counts.
- By Entity Class
- Filters the list by entities from a specific entity class.
The Map Error Report Dialog¶
This dialog is opened by clicking on its related item in The Map Menu.
It checks the map for errors and shows them in an error report list.
- Errors found
- The list of errors found in the map.
- Description
- Detailed description of the currently selected error.
- Go to error
- Centers the selected error in the views.
- Fix
- Fixes the selected error.
- Fix all of type
- Fixes all errors of the same type as the selected error.
The Transform Type-In Dialog¶
This dialog is activated by clicking on the Transform item in The Tools Menu.
It allows you to translate (rotate, scale and move) and object by entering exact translation values, instead of translating the object by mouse.
Mode¶
The transformation mode is set here:
- Rotate
- Object is rotated by the transformation values.
- Scale
- Object is scaled by the transformation values.
- Move
- Object is moved by the transformation values.
Values¶
- X
- Transformation in x direction.
- Y
- Transformation in y direction.
- Z
- Transformation in z direction.
The Surface Properties Dialog¶
This dialog represents the settings of the Edit Surface Properties Tool. Please refer to the Edit Surface Properties Tool documentation for more information.
The Entity Inspector Dialog¶
This dialog presents detailed information about your map and its entities. It shows you the hierarchically structured list of entities that your map is composed of, allows you to inspect the properties of each entity, and provides a built-in source code editor for the map script.
The dialog is opened by selecting the Entity Inspector item from the Edit menu.
The following text describes the three “tabs” that implement the main features of the dialog.
Entity Report¶
The Entity Report keeps a list of all entities that exist in the map. It is used to easily manage, find and select individual entities, and thus provides a convenient alternative to locating entities in your map manually.
The entities are listed by the name of their entity class and their
instance name, if one has given, e.g.
“static_detail_model (TreasureChest)
”. Clicking on a list entry
selects the related entity in the 2D and 3D views of the map as well.
You can select multiple entities at the same time by holding the
CTRL
or SHIFT
key while clicking on an entry: this works just
like in Windows Explorer. The presented list is sorted in alphabetical
order and can be filtered by several options as described below.
- Go to
- Centers the 2D views on the selected entities.
- Delete
- Deletes the selected entities (both from the list and from the map).
- Filter
The controls in the filter box determine which entities are included in the list above.
- Brush Entities
- When checked, the brush-based entities are included in the list.
- Point Entities
- When checked, the point-based entities are included in the list.
- Include hidden Entities
- When checked, entities are included even though they are normally hidden (as part of a VisGroup) in the 2D and 3D views.
- By Key/Value
- You can reduce the list of entities to those whose properties match the given key/value pattern.
- Exact
- Toggles if the key/value pattern has to be an exact match, or if partial match counts as well.
- By Entity Class
- If checked, only entities of the specified entity class are shown.
Properties¶
The Properties tab is one of the most important dialogs in CaWE, because it allows you to inspect, set and modify all of the advanced attributes of the currently selected entity.
The properties are presented in tabular form as pairs of keys (on the
left) and their related values (on the right): The set of keys that
are available for an entity is defined by the entity’s class. It can
therefore not be changed directly within CaWE. Adding, removing or
renaming keys is only possible via the game’s EntityClassDefs.lua
script, which contains the definitions of all entity classes for a game.
Updating this script possibly affects all maps of a game, and is
consequently normally never done for an individual map, but in the early
planning stages of a MOD.
Changing the values however is the daily bread and butter of a mapper. Therefore, doing so is not only easy, but it has also been made as convenient as possible. In most cases, you just click into the desired value field and enter a new value directly. For each variable (that is, a key/value pair), also the variables type is known to CaWE, which is uses to assist you entering correct values:
- keys that only accept integer values do not accept commas, periods or letters,
- keys that accept boolean values or a choice from an enumeration act accordingly,
- keys that expect colors will provide you a color chooser and an automatic preview,
- keys whose values are multi-line strings come with an appropriate editor,
- keys that expect file names (e.g. for sounds, models, etc.) will provide you with a three-dots “…” browse button (which is very helpful (!)),
- and so on.
We’re currently working on improving this feature further, e.g. with “Play” buttons for listening to sound files, a preview facility also for model files, etc.
Note that at the top of the dialog, there is a summary about the number of selected entities and their classes. At the bottom of the dialog, a short help text for the currently selected key is provided. Help is also available in form of tool-tips for the key the mouse pointer is currently over.
Classname¶
Changing the class of an entity is a special action, because it
corresponds to deleting the entity and re-instantiating it under a
different class but with the same properties. Nonetheless, you can use
the special classname
property to change an entity’s class like any
other property: You’re provided with a choice box that contains all
possible new classes for that entity, and just making the selection
reincarnates the entity as an object of the new class.
Please note that currently there is a restriction that brush-based (solid) entities can only be converted into entity’s of classes that are brush-based, too. Similarly, entities that are point-based can only be converted into entity’s that are point-based, too.
Undefined Properties¶
Sometimes entities come with key/value pairs that have no corresponding
definition in their entity class. Such key/value pairs can occur
occasionally e.g. when an entity was converted to a different class (see
below), an entity class got a variable definition removed after a map
has already been made with it, or when an entity has been imported from
an entirely different game. The entity might then bring in a key named
e.g. light_pulse_frq
that is utterly unknown in the context of the
current games entity definitions.
Another but similar case occurs when the entity’s class name is unknown among all entity classes of the current game. This typically happens when you try to import for example an entity of class “stuffed_animal” of a children’s game into a game about aliens or robots, or in any other case when the current game just knows nothing about the imported entity class.
In these cases, there is no corresponding definition for such keys in the game definition. CaWE therefore collects such occurrences separately and keeps them under the special category “Undefined Properties”.
Because undefined properties are not dealt with by the game in any way, you’re free to change and modify them at will. You can even right-click them to open a context menu that allows you to rename them, to add new ones or to delete them.
In most practical cases, you’ll want to get rid of undefined keys though, which can be achieved by renaming them to something meaningful, by deleting them, by changing the entire entity class to something else, or a combination thereof.
Background Colors¶
The property grid employs several background colors in order to indicate certain conditions of the values:
- White background indicates that this is just a normal value.
- Light blue background also indicates a normal value that also happens to be the entity class’s default value for this variable.
- Light orange background is used whenever multiple entities are selected that have different values for the same key. You can still enter a new value for such keys: The key of each selected entity will then be set to the same new value and the background color will change back to white accordingly.
- Light red background is currently used at only one occasion: When you
set a
model
key and have not yet specified a value for acollisionModel
, thecollisionModel
variable is temporarily highlighted with this color in order to remind you to also set a collision model.
Working with multiple entities¶
The Properties tab works also very well when more than a single entity is selected, or in fact, any number of them is selected at the same time. In order to present you the properties of multiple entities, CaWE “overlays” them for you, so that even great amounts of simultaneously selected entities remain easy to understand and manage.
In order to achieve this, CaWE makes sure that properties that are candidates for layering, but otherwise incompatible with each other for any reason (e.g. because the property is known only to some but not all of the entities, or defined multiply with different types), are treated specially as “mixed” properties. A property that is marked as “mixed” has attributes in one entity that are non-existent or different in another, which generally makes them incompatible to each other.
Such mixed properties are therefore listed in another separate category, and they are protected from editing (“read-only”). This makes sure that you can see such affected properties, but not inadvertently get nonsensical values written into lots of entities. Note that this is not a restriction, because it’s just another way of saying: “Stop! If you assign a value to this property, there is at least one entity affected for which doing this makes no sense at all.”
If you still want to edit a property that is listed as “mixed”, there is an easy way to overcome the problem: Just select fewer entities until the entity that was the reason for the property being listed as “mixed” is gone. When no conflicts remain, the property gets re-listed among the normal properties, and you can edit it freely.
Map Script¶
In the Map Script tab, you can view and edit the source code of the maps current script.
(FIXME!) This feature is not yet implemented – I’m very sorry. Both the functionality and the documentation will be provided later. However, please note that the game code and the Cafu engine already fully implement and support map scripting! Use any text editor of your choice in order to program your map scripts independently and outside of CaWE. In fact, all the example scripts that come with the Cafu releases have been written that way. 😉
Entity Guide¶
An entity is an object that has characteristics which are different to the normal world brushes. There are two kinds of entities in Cafu. These include brush-based entities and point-based entities.
- Point-based entities
- exist at a specific coordinate in space and be can be thought of as a reference point. Although these entities may refer to objects that actually have a volume, for example a monster, they are only treated as points in CaWE, and the Cafu engine provides the volume later in the game. An example is a monster entity: In CaWE, it just represents the point where the monster will be, in Cafu, it will actually be there.
- Brush-based entities
- are related to at least one brush or bezier patch and thus have a volume. Examples for brush based entities include doors and platforms, bodies of water, area triggers, etc.
Brush-Based Entities¶
Solid entities are world brushes that have extra characteristics. Note: This list is not fully complete.
func_illusionary¶
This is a func_wall with no clipping. The player can walk through a func_illusionary, making it useful for secret paths.
func_water¶
This is the entity for water.
func_ladder¶
The player can climb up a func_ladder. Please note that this entity is invisible, so you need to place a textured brush behind it.
func_breakable¶
This is a breakable object. You can set the material as glass, wood, metal, flesh, cinder block, ceiling tile, computer, unbreakable glass or rocks. You can also set the strength of the object.
func_particle_generator¶
This entity emits particles. It could be used for fire, water etc.
func_pushable¶
This is an object that the player can push around the map.
func_terrain¶
This is the entity used to add a terrain to a world. You must specify a heightmap for the terrain, and a detail texture. See Creating heightmaps for your terrains and the NewMaterials document for more info about terrains.
Point Entities¶
info_player_start¶
The info_player_start is the spawn point for the character(s). You must have at least one in any map you create, and you must ensure that every info_player_start is inside the map.
PointLight¶
This is a light to complement the texture area lights. You used to have to put one of these in front of every surface that emitted light, but now you should not need to use this entity much, as any texture that looks like a light will emit light in the game.
static_detail_model¶
Please note that this entity doesn’t clip, so you need to put a clip brush around the model if you don’t want the player to be able to walk through it.
Weapons, Ammo and items¶
- weapon_shotgun (Shotgun)
- weapon_357handgun (357 Handgun)
- weapon_9mmAR (Assult Rifle)
- weapon_crossbow (Crossbow)
- weapon_rpg (RPG Launcher)
- weapon_handgrenade (Grenade)
Some other weapons are included, but most of them don’t work.
Monsters¶
- monster_butterfly - A group of three butterflies that fly around in circles.
- monster_companybot - The default Trinity bot that follows you around.
- monster_eagle - An eagle which flies overhead. Requires a lot of space.
Tree¶
(FIXME!) I don’t know what this is…
Compiling Maps for Cafu¶
When you have finished editing a map in CaWE, you’ll want to run it with Cafu. The engine however requires that the map is in a precomputed form, and this section describes how you turn your map into a fully precomputed world file. The process of turning your cmap map file into a for the engine usable cw world file is called compiling.
As to not force you to run the compile procedure for all your cmap files by hand, the CaWE mapping editor provides a “Compile” menu with which you can easily and very conveniently accomplish this task. In this section, you’ll learn how to use it.
You will find the “Compile” menu in the top menu bar
of CaWE. It’s items can roughly be separated into three distinct groups:
The upper group tells CaWE what to do, the middle group says how to
do it and the lower group is for stopping the compile process early.
The function of all items is explained in greater detail below:
Step 1: The compile steps¶
The upper group of menu items tells CaWE which steps of the compile process should be run. You can turn the individual parts on or off by checking or unchecking the mark in the appropriate line.
- Save Map: Saves the map. Checking this does exactly the same as a click on the “File → Save” menu item before compiling the map. Having this checked is practical and recommended when you work on a map and want to test it “live” in the Cafu engine every now and then, because it makes sure that the compilers pick up the latest version of your map with the most recent changes.
- Run CaBSP: This is the crucial step that runs the CaBSP compiler on your map. CaBSP takes your map file and creates a world file for use by the Cafu engine from it (the map file is not modified). As all other compilation steps build on this one and the generated cw file, you cannot turn it off to omit CaBSP.
- Run CaPVS: Runs the CaPVS compiler on the intermediate result obtained from CaBSP. CaPVS precomputes the PVS (Potentially Visibility Set) for the world file. This can be a lengthy process on its own, and you may wish to skip it when you’re just testing your map. However, it also has a potential for improving the rendering performance of your map significantly, so you should never leave this out for release maps.
- Run CaLight: Runs the CaLight compiler on your map, which precomputes the static lighting of your maps by using physically accurate Radiosity methods. CaLight too can take very much time to complete, and should therefore never be run without a preceding CaPVS pass. However, for testing you may want to skip CaLight as well as CaPVS, because your map will be full-bright when CaLight is not run, which may be sufficient for checking e.g. the geometry or entity placement during map development.
- Start Engine: If this entry is checked, Cafu will automatically be launched with your map when the compiling process is finished.
Step 2: Starting the compile process¶
After you have selected which steps should be included in the compile process, you can start it with varying quality settings by clicking on one of the three items of the middle group (“Quick”, “Normal”, or “High Quality”). These settings mostly affect the quality of the lighting generated by CaLight, and therefore have a direct impact on its run-time.
After you started the compile process, a console window opens, showing compile details and progress information. Note that you can simply close the console window at any time and continue to work on your map while the compilation process keeps running in the background. Just use the “View → Screen Elements → Console” menu to toggle the console window on and off. The three menu items to start a compile will be grayed-out while another compilation is running, so that starting two compile processes simultaneously is not possible.
However, you can stop the entire currently running compilation process prematurely by clicking on the “Compile → Abort” menu item.
If you activated the “Start Engine” item, Cafu will be started when the compile process is complete and you’ll just have to click on “OK” in the Cafu dialog to start and play your map!
Tips, Tricks and Trouble-shooting¶
Using the “Compile” menu requires that you have setup the “Configuration” dialog of CaWE completely and properly. If a compiler cannot be run correctly, please check if you got all the executable file names right in this dialog. Please refer to Installation, Initial Configuration and De-Installation for more details.
If your map turns out to be pitch-black when run in the engine after the last compilation step, a likely cause is that you kept the CaLight compiler enabled, but did not place any radiosity light source (i.e. no light or sky material). For checking this quickly, just disable CaLight in the “Compile” menu, then start the compilation again and review the result in the Cafu engine. Thereafter, you may want to place some light sources into your map by applying materials that cast radiosity light, and re-enable CaLight again in order to compute a proper, realistic radiosity solution.
For quick tests during map development, you can save a lot of compile time by turning off the CaPVS and CaLight compile steps. You may get very low frame-rates and only full-bright lighting, but that’s usually fine for checking the map geometry. When you’re done, or about to release your map for others, you definitively should compile it once with CaPVS and CaLight enabled, in order to obtain the maximum speed and quality.
Very advanced users can also compile their maps manually at the command-line. This offers the possibility for further customisations of the compile process. Compiling maps at the command-line is explained here.
Compiling Maps at the Command-Line¶
When you have finished editing a map in CaWE, you’ll want to run it with Cafu. The engine however requires that the map is in a precomputed form, and this section describes how you turn your map into a fully precomputed world file.
In order to use CaBSP, CaPVS and CaLight “by hand” (rather than from within CaWE), you should be familiar with the command-line interface of Windows or Linux, because these programs just cannot be started by a simple double-click on them.
Under Windows, you can open the command-line window by opening “Programs
→ Accessories → Command Prompt” (in German: “Programme → Zubehör →
Eingabeaufforderung”) from the Start menu. Initially, the window shows
the directory you are currently in. You can browse into the parent
directory by typing cd ..
, as for example in
C:\Windows> cd ..
C:\>
and you can enter a directory by typing
C:\> cd directoryname
C:\directoryname>
(Replace “directoryname” with the name of the directory that you want to
open.) Other useful commands are dir
that shows all files that are
in the directory you are currently in and e:
(for example) to change
the current hard drive.
In order to run the programs with the commands presented below, you’ll
first have to browse into the directory they are in (which is the
Cafu-9.06
directory).
Compiling step 1: CaBSP¶
This program takes a cmap map file and creates a cw (Cafu world) file from it. Example:
C:\Cafu-9.06> CaBSP Games/DeathMatch/Maps/MyMap.cmap Games/DeathMatch/Worlds/MyMap.cw
(!) WARNING: The specified destination file
(Games/DeathMatch/Worlds/MyMap.cw
in the above example) gets
overwritten without prior notice! This is also true for mis-spelt file
names. For example, if you type Games/DeathMatch/Maps/MyMap.cmap
instead of Games/DeathMatch/Worlds/MyMap.cw
– catastrophe! As with
most other computer software, in order to prevent a disaster, please
backup your filesbeforeyou begin!
For quick tests during world development, you might want to skip the next two compiling steps (CaPVS and CaLight). You can run the file obtained from the CaBSP tool directly in the Cafu engine. It will be unlit and without PVS information (which results in a lower frame rate), but is usually sufficient for early tests.
Compiling step 2: CaPVS¶
This program creates the Potentially Visibility Set for your worlds. Example:
C:\Cafu-9.06> CaPVS Games/DeathMatch/Worlds/MyMap.cw
The CaPVS compile switches¶
Even though the latest versions of CaPVS have become fast enough to deal with even the most complex worlds within reasonable time bounds, sometimes it may still be preferable to obtain faster results (at the cost of accuracy).
Before you read on, though, my advice is to simply skip the rest of this
section, and continue with the next. Why? Well, the compile switches
introduced below were made at a time when CaPVS was inherently slower.
Since then, it has undergone many algorithmic improvements, and the
switches were only left for safety and as a last resort. I hardly ever
use them myself (although their implementation is interesting), and
nowadays never use them for release compiles (the worst world I have
takes 27 hours on a 866 MHz Pentium III this way). During world
development, you should skip CaPVS entirely rather than trying to tune
it for faster compilation. Also keep in mind that the proper use of
func_detail_object
entities can have a big impact on performance in
general, and on CaPVS compile time in particular.
Anyway, the latest version of this tool has two new command line switches that were made to lower its compile times by effectively trading quality for speed. Both switches control the creation of SuperLeaves. To understand what SuperLeaves are, you must first have a rough idea what leaves are: Leaves are spatial convex cells into which CaBSP subdivides your world and in which the action of the game takes place later on. Simplified spoken, you can imagine that each room of your world corresponds to a leaf. CaPVS then determines the PVS by calculating if any unobstructed lines of sight exist between any pair of two leaves. It is not only the sheer number of leaves that makes the computation so slow, but also their spatial relations among each other. In some cases, there are unnecessarily too many leaves for the purposes of CaPVS, and it is preferable to merge some of them. Thus, a SuperLeaf is a set or a group of simple leaves. One could say that SuperLeaves subdivide the world in cells as leaves do, but the subdivision is “coarser” than with the simple leaves. When you run CaPVS on a world, it tells you how many SuperLeaves it constructed from the simple leaves. By default (without command line switches), the SuperLeaves are identical to the simple leaves, as is their number.
Now about the actual switches: Running CaPVS without any parameters (not even a world name) will print out a self-explaining usage information. I’ll not repeat it here, but rather give you some tips on the usage of the two mentioned switches. Note that you always trade quality for speed, but the compromise is usually a very good one (quality remains high even for quite fast compiles).
In general, try to reduce the compile time with care. If the situation was actually hopeless before, it does not make sense to use the switches to bring the compile time down to a few minutes or seconds. (That would be more like not running CaPVS at all.) Rather, a good idea would be to send me an email with a brief description of the problem, along with the world you are trying to compile (I’ll only believe that you created a world that’s too hard for CaPVS after I’ve seen it myself 😉 ).
Then, consider two strategies: You can either choose to work “top-down” by choosing the parameters such that the number of SuperLeaves is gradually reduced in small steps. The quality remains high, but the downside is that you possibly have to wait another long time until you know if the reduction was enough.
Thus, I’d recommend a “bottom-up” approach: Initially reduce the number of SuperLeaves a lot, start with a quite small number. If CaPVS then takes only a few minutes, but you want it rather to spend some hours, adjust the parameter values carefully so that the number of SuperLeaves increases slowly and gradually. You’ll probably have to re-try and experiment a few times until you get a feel of it.
Finally, you should prefer the -minAreaSL
switch over the
-maxRecDepthSL
switch, because the former is more sensitive to the
actual world geometry. Do not worry about high numbers on
-minAreaSL
. When I last used it, I usually had values ranging from
1,000,000 to 5,000,000.
Compiling step 3: CaLight¶
This program calculates the lighting for a map. This program can take very long too, but you have better control over it by specifying command line switches. Examples:
C:\Cafu-9.06> CaLight
C:\Cafu-9.06> CaLight Games/DeathMatch/Worlds/MyMap.cw
C:\Cafu-9.06> CaLight Games/DeathMatch/Worlds/MyMap.cw -BlockSize 8 -StopUE 2
C:\Cafu-9.06> CaLight Games/DeathMatch/Worlds/MyMap.cw -fast
The first line prints out detailed usage information for the CaLight tool, the second line runs default lighting, which is recommended for most cases. The third and fourth lines are for very fast lighting, which is useful for quick tests during map development.
Please note that it is almost never reasonable to set BlockSize below 3 and StopUE below 0.1 for highest quality lighting, even though that is possible (some of the worlds of the Cafu demo releases were compiled with a StopUE of 0.05).
During the second phase of the computations (“bounce lighting”), note
that you can interrupt the program by pressing the SPACE
button.
That’s sometimes useful for quick tests during map development.
Finally, a word about memory consumption: CaLight requires plenty of it! I would recommend to run CaLight only on computers with at least 1 GB of RAM, it may or may not run with less. If permanent swapping (extensive disk activity) occurs during the bounce lighting phase of CaLight, better abort it! Under such circumstances, it will proceed very slow anyway, and the lengthy swap activity is certainly not healthy for your hard-disk. (!)
Done: Running the world with Cafu¶
If not already there, copy your world into the
Games/DeathMatch/Worlds
directory if you made the world for the
DeathMatch MOD, or into the Games/OtherMOD/Worlds
directory of the
MOD you made the world for. Then simply run Cafu.exe
as stated in
the user manual of the current demo release. Your world will be listed
among the other worlds in the dialogs world list (“server options”).
Creating Height-Maps for your Terrains¶
The shapes of the terrains that you can create with The New Terrain Tool are defined by height-maps. A height-map is usually a square gray-scale image whose black pixels represent the lowest heights (0%) and whose fully white pixels describe the highest heights (100%). The gray values between them represent intermediate height values – the brighter a pixel, the higher is the resulting terrain at that spot.
CaWE and Cafu support height-maps in all the image file formats that are
also supported for textures (jpg
, png
, tga
and bmp
), as
well as Terragen (ter
) and portable graymap (pgm
) files. The
image file formats usually have a precision of 8 BPP (bits-per-pixel),
while the ter
and pgm
formats have a much higher precision of 16
BPP, and are therefore the preferred choice for height-maps.
Height-maps must also meet the additional requirement of having side lengths of (2:sup:n+1) * (2:sup:n+1) pixels, where n is an integer between 1 and 15. Examples of typical height-map dimensions are 129*129, 257*257, 513*513 and 1025*1025.
Programs for Creating and Editing Height-Maps¶
Creating and editing high-quality height-maps can be a complicated and demanding process that typically requires the assistance of specialized software. I’ve intensively tested many software packages for this purpose, many of which just don’t meet the requirements. Typical problems include limited or broken importers and exporters (e.g. only to and from proprietary file formats), limits in the supported high-map dimensions (e.g. only 2n * 2n, not 2n+1 * 2n+1), usability, stability (e.g. frequent crashes) and the inability to switch off the “relative height editing mode”, which seemingly allows users to dig deeper than 0% or raise terrain higher than 100% by adjusting the relative height of all other terrain.
The following lists mentions several programs that I consider useful or relevant for creating and editing height-maps. None of them is perfect or can do everything that is needed all in one program, so you might be also interested in reading the [ (FIXME!) Link to tutorial about how the TechDemo terrain was made. ] tutorial.
CaWE¶
The obvious and best choice for editing the height-maps of terrain entities is CaWE.
It is possible to edit and modify height-maps directly in the 3D view of CaWE, in a “live” manner that naturally and immediately shows the interactions with other elements of the map, as for example brush-based buildings and walls, other entities, etc. For more information about the terrain tool please check here
Note that although CaWE would be the ideal place for height-map editing and modification, it is not necessarily the best place for height-map creation. Although that would be and will be possible, too, other programs below that are specialized on height-map creation may do a much better job in creating the initial height-map, especially if very large, natural-looking shapes are desired. In such cases, you would use another program to create the initial height-map, then add it to your map in “rough” form using The New Terrain Tool, and then continue to edit the fine details in CaWE, for example the alignment with buildings, other brushes, etc. You may want to have a look at the [ (FIXME!) Link to tutorial about how the TechDemo terrain was made. ] tutorial in this regard.
Regular 2D Applications¶
Although not meant to visualize the actual 3d surface itself, nearly all 2d applications are able to provide a decent way of creating a highmap. However most of these methods are more likely to create a basic uneven surface that can then be altered inside the Cafu Editor for more precise interaction with bsp or mesh based geometry.
While most terrain specific tools offer much more natural control over the final result (like eroding based on water and wind) almost every 2d application can provide hightmaps.
Noise filter (like perlin noise) are very powerful and can create a wide variety of surface distortions that are great as a base. There are many different applications out there commercial and free, yet we would like to prefer free ones.
Gimp (Freeware)¶
Obviously the most common freeware 2d application, that mimics the commercial Adobe Photoshop in many ways and beyond. It matured over the years into a reliable 2d package and should be considered as a professional tool. By using filter and custom brushes it is a very good way to start a decent highmap
Gimp is loacted here: http://www.gimp.org/
Create basic landscape http://springrts.com/wiki/Height_Map_Tutorial
Flash based (Freeware)¶
L3DT (Free/Commercial)¶
Geo Control 2 (Demo/Commercial)¶
World-Machine (Free Edition/Commercial)¶
Leveller (Commercial)¶
Looks like it offers quite a few different tools to work with, however the price of 199 dollar is way too much and there is not much indication about when the last update actually took place. http://www.daylongraphics.com/products/leveller/
Terragen (Free Edition/Commercial)¶
This is the software for terrain rendering, but due to it’s “relative height editing mode” I’d not recommend it for height-map creation or editing. Terragen is very good though at generating a base (ground) texture from a height-map! http://www.planetside.co.uk/
Earth Sculptor (Commercial/outdated)¶
A small app, that works fine and allows for decent manipulation. Unfortunatly it’s development stopped since 2008, but still its worth noticing it http://www.earthsculptor.com/index.htm
Other 3D Engines¶
There are a few games with a great support for terrain editing, such as Crysis or Unreal3. Epic offers the Unreal Developer Kit as a free alternative, and the terrain editor is capable of exporting. This may sound strange but still offers another option which is also completly free.
Other Programs¶
If you have experience with other programs, please add them here.
There are several other good programs, but I don’t use them often. Maybe one of them has released a new version in the meanwhile that addresses some of the problems of older versions, so it might be worthwhile to have a look at them! For example, for basic terrain creation, programs like TerraBrush, Terraformer 1.8b or TerraMaker already do a good job.
Summary¶
Use any of the above mentioned programs for creating the initial height-map. However CaWE will allow you to further edit these maps conveniently in the editor. If you must fine-tune them before that, patience and creativity is required, although the above programs will help with that, too.
Once your height-map is complete enough for use, you’ll also want to have a base texture for it that represents the color of the ground and is used in the material definition with which your terrain is rendered. While the texturing of the terrain might be possible in future versions directly in CaWE, too, I currently just import my height-maps into Terragen for this purpose, make sure the dimensions (lateral size and altitudes) are correct, setup the Terragen materials, set the sun appropriately (full-bright and no shadows) and turn off all atmospheric effects, set an orthogonal camera view and then use the Terragen rendering result as the base texture.
The Font Wizard: Creating new fonts¶
Preparing new fonts for rendering text within a GUI is very easy. The key idea is to convert a font file (e.g. one of those installed with your OS, or downloaded from the Internet) to a set of graphics files that the Cafu GuiSys can use:


Step 2: Click the “
…
” browse button to select the
desired font, or enter the filename directly into the related field.
Microsoft Windows users, please note that for some versions of
Windows, most notably Windows 7, Microsoft has chosen to
special-case the related “File Open” dialog so that the system folder
C:\Windows\Fonts
cannot be browsed. (The problem is neither related
to access rights nor is it specific to CaWE.)
In order to overcome the problem, i.e. if you want to use a system font
from C:\Windows\Fonts
with the Font Wizard, we recommend to either
- type the path and file name of the desired font manually into the input field, or
- at the command prompt copy the desired font files from
C:\Windows\Fonts
into any other directory, then use the “…
” browse button to select the related file.



Creating fonts at the command prompt¶
As an alternative to the above, fonts can also be created with the
MakeFont
program at the command prompt. Here is the sequence of
commands that creates the same font as above:
d:\Dev\Cafu> cd Fonts
d:\Dev\Cafu\Fonts> mkdir Segoe
d:\Dev\Cafu\Fonts> cd Segoe
d:\Dev\Cafu\Fonts\Segoe>..\..\MakeFont.exe C:\Windows\Fonts\segoe.ttf -m=Segoe
The Cafu Font Maker, version July 01 2009.
Portions of this software are copyright (c) 2006 The FreeType Project
(www.freetype.org). All rights reserved.
MakeFont
takes two parameters: the name of the font file whose font
you want to use with Cafu GUIs, and the base name of the font materials.
The base name is specified as -m=<base_name>
. Although MakeFont
will also work if you omit the -m=…
part, your fonts will not work
properly without it, so please make sure to include it. (The Cafu MatSys
needs this option in order to be able to render the fonts properly.)
Using the newly created font¶
Your font is now ready to be
used in a GUI. Its name always begins with
Fonts/
, followed by the
previously chosen font name. In our example above, the font name is
Fonts/Segoe
.
In the GUI Editor, enter the font name into the appropriate field of the window that should use the font.
Alternatively, if you edit the GUI script manually, just add
self:set("font", "Fonts/Segoe");
to the appropriate OnInit()
function to use the new font.
GUI Files Explained¶
Each GUI comprises several files on disk, such as the GUI scripts, material definition files, and texture images.
GUI files can be created with the GUI Editor, written by hand, or a combination of those:
- The GUI Editor allows users to define and design the contents and layout of the windows that compose a GUI. However, the work in the GUI Editor is focused mainly on static aspects like window position and size, texts, colors, borders, etc.
- Everything “dynamic” and all sorts of effects can, by their nature, not be added by means of the GUI Editor, but must be written as custom, hand-crafted script code that augments the script that is auto-generated by the GUI Editor each time the “static” part of the GUI is saved.
One key question addressed in this section is how we can combine hand-crafted script code and editor-edited script code, while keeping both separated so that they don’t overwrite each other.
In general, when you save a GUI in the GUI Editor, the editor creates or re-creates some of the files it is composed of, updates others, and leaves alone the rest. The result is normally exactly what you want and expect, but sometimes you may wish to or must hand-tune the details (such as the GUI scripts or material definitions) without and independently of the GUI Editor. In such cases, it is very helpful to understand the files that belong to a GUI.
This section explains the files that together form a GUI, how they relate to each other, and how hand-crafted and editor-created scripts can peacefully coexist.
One directory per GUI¶
Although not a technical requirement and not enforced by the Cafu GUI code (and in fact, at the time of this writing, not yet implemented by the example GUIs that ship with Cafu), it is highly recommended to save each GUI in a directory of its own. This
- explicitly groups all files that logically form and belong to the GUI, and
- makes packaging a complete GUI in a
my_GUI.zip
archive possible, so that the GUI can easily and safely be distributed, shipped and handled.
The name of the directory should match the file name of the GUI. That
is, if your GUI’s file names are CallLift_init.cgui
and
CallLift_main.cgui
, it should be stored in a directory with the same
name CallLift/
(or in a zip archive with the same base name
CallLift.zip
).
Note that when you are saving a new GUI that does not yet have a separate directory, you can use the “New Folder” button (or right-click context menu) of the “Save” dialog to create such new directories as required.
cgui GUI definition files¶
The cgui
files are the core files of the GUI: They contain the
definitions for the positions, sizes, colors, texts, effects,
animations, hierarchy and other properties of the windows that form the
GUI.
cgui files are Lua scripts¶
The Cafu Engine and the GUI Editor load cgui
files as
Lua scripts, and as such they can be inspected
or edited in a text editor.
The GUI Editor is usually used to create and edit the static aspects of
GUI windows, automatically generating the related script code when
saving the file. Dynamic aspects like animations or other kinds of
effects typically require adding custom script code, so editing cgui
files (usually the _main.cgui
file) is something that you’ll likely
want to do often.
See the Lua Scripting Overview and the GUI Scripting Reference Documentation for more details.
Augmenting GUI Editor scripts with custom script code¶
For one GUI there is usually a pair of cgui
files, one suffixed
_init.cgui
and one suffixed _main.cgui
. For example:
d:\Dev\Cafu\Games\DeathMatch\GUIs> dir Teleporter\*.cgui
Teleporter_init.cgui
Teleporter_main.cgui
The _main.cgui
file is for your hand-written GUI script code, if
any, and is never touched or overwritten by the GUI Editor (with one
exception, see below).
The GUI Editor also writes a secondary cgui
file whose name ends
with _init.cgui
. This file is written anew each time the GUI is
saved, and contains GUI window definitions whose script code was not
hand-crafted, but who were created or edited in the GUI Editor.
The two cgui
files are linked as follows: When the Cafu code loads a
GUI, it opens the _main.cgui
file (Teleporter_main.cgui
). This
file contains a statement like
-- Include the GUI Editor generated file.
dofile("Games/DeathMatch/GUIs/Teleporter/Teleporter_init.cgui");
-- Add your hand-written custom code below this line.
-- ...
in order to include and process the secondary _init.cgui
along with
the main file.
The only exception when the GUI Editor touches the main
Teleporter_main.cmat
file is when the file does not yet exist, or
doesn’t contain the dofile()
reference to the init file. In this
case, the _main.cgui
would not be loaded at all, and thus the GUI
Editor inserts the dofile()
line into the _main.cgui
file.
In summary, the goal of keeping two separate cgui
files that are
linked as described above is to keep your hand-crafted GUI script code
and the GUI Editor edited window definitions cleanly separated, without
any danger of one overwriting the other:
- When you edit your GUI in the GUI Editor, you only load and save file
Teleporter_init.cgui
. - All hand-written code enters file
Teleporter_main.cgui
instead. - The connection between the two files is made by the
dofile()
statement.
cmat material definition files¶
The cmat
files contain the material definitions for the graphical
elements of this GUI.
At the time of this writing, the materials for GUIs are still defined in the “global” material scripts for the MOD, but for the future we intend to have separate material scripts for each GUI that work analogous to cmat material definition files for models.
Texture images¶
The texture images are referenced from the material definition scripts. See the documentation about the Cafu Material System for more details.
The Model Editor: Introduction¶
The Cafu Model Editor answers the question:
“How do I get my models into Cafu?”¶
- load and import model files,
- support many file formats (see below for a list),
- let you inspect the loaded model both graphically and structurally,
- enable you to tweak and adapt the model (e.g. import additional animations, remove unused skeleton nodes, etc.)
- set or adjust all Cafu-specific settings (such as animation properties, GUI panels, collision details, etc.),
- assign and edit render materials,
- save the resulting model in Cafu’s own file format.
Summarized, the Cafu Model Editor makes your models ready for use in the Map Editor and the Cafu Engine.
What the Model Editor is not¶
The Cafu Model Editor is not, despite its name, a general-purpose editor that lets you shape meshes or create a model from scratch: There are many commercial and free programs for this purpose already that we don’t intend to rival. In fact, model artists use one or more of these programs early in the work pipeline to create and shape the model, then use the Cafu Model Editor as described above.
Also, with the Model Editor we don’t attempt to provide a graphical user interface that saves you from editing script code: Many models files are scripts, and accessing some features is only possible by editing the script code in these files. Our goal is to employ the Model Editor for everything that is hard or impossible to accomplish with model scripts or otherwise. Tasks that are best solved in script code are left in script code, for which we provide thorough documentation in order to make them easy to understand and master.
With these key ideas, we can achieve the most effective solutions for all tasks about models.
Starting the Model Editor¶
Like
the other asset editors, the Model Editor is a part of CaWE. You start
it via menu items
- File → Open… (Ctrl+O) or
- File → New → New Model (Ctrl+Shift+N)
With both menu items, you’re next presented the File Open dialog to open a previously created model.
Check out the Main Window and the How-Tos for the next steps.
Supported File Formats¶
At this time, the following file formats are supported:
Extension | Description |
---|---|
.cmdl |
Cafu Engine native model file format |
.3ds |
3D Studio 3DS |
.ase |
Ascii Scene Export, 3D Studio Max ASE |
.dxf |
Autodesk AutoCAD DXF |
.dae |
Collada DAE |
.fbx |
Autodesk FBX |
.lwo |
Lightwave Object LWO |
.md5 |
Doom3 / Quake4 MD5 |
.mdl |
Half-Life1 MDL |
.obj |
Alias OBJ |
The Main Window¶
Starting the Model Editor¶
Like
the other asset editors, the Model Editor is a part of CaWE. You start
it via menu items
- File → Open… (Ctrl+O) or
- File → New → New Model (Ctrl+Shift+N)
With both menu items, you’re next presented the File Open dialog to open a previously created model.
cmdl
file format that is specific to
the Cafu Engine: Unlike any other file format, cmdl
models files
reflect all the model features that are implemented in the Cafu
Engine.Main Window Elements¶
3D View¶
The 3D view shows the currently loaded model. The mouse and keyboard navigation works exactly like in the 3D views of the Map Editor: See
- Navigating the 3D views and
- the related video
for details.
Tip: Especially the MMB
can be helpful for effective navigation in
the 3D view.
Detail Panes¶
Model details, scene settings and some dialogs of the Model Editor are presented in panes: Small windows that can be docked to the borders of the parent frame, or be “floating” freely on the desktop.
If you grab a pane by its title bar and drag it over the screen, a
translucent highlight will indicate where the pane will dock when the
left mouse button is released. Press and hold the CTRL
key while
dragging the pane in order to prevent it from docking at all (it will
remain floating instead).
If you close a pane, use the appropriate item in the View menu to show it again at any time.
Model Element Panes¶
Most of the panes present model elements of a specific type:
- the skeleton (also called the joints hierarchy),
- meshes,
- skins,
- GUI fixtures,
- animations,
- channels,
- submodels, and
- level-of-detail models.
Note that for most model elements, there are in fact two panes: One that shows the list of all elements in the model, and one that shows the details of the currently selected element.
For example, the “Skeleton” pane lists all joints in the model, hierarchically arranged. Double-click any of them to bring up the “Joint Inspector” that shows the properties of the currently selected joint.
On the following pages in this manual there is one chapter for each element type. Each chapter explains the model element type and its related “list” and “inspector” panes.
The Toolbar¶
The toolbar provides quick access to the most frequently used menu items.
Move the mouse over any toolbar button to see a tooltip that describes the purpose of the button.
How-Tos¶
How do I …¶
… get my model into Cafu?¶
See this video for details.
Additional notes:
- When watching the video, change the playback quality to “720p HD” if possible.
- There is no audio track in this video.
- Use the New Entity tool for placing the
newly created
.cmdl
model into a map. Watch the Placing a Model tutorial for related information. - If you want to make adjustments later, both the
.cmdl
model as well as the material definitions can be edited as shown above also after the model has been placed into a map or world file. The changes will take effect when the program is next restarted. - In the video, why did we close the model window before editing the
material definitions?
When you save a model file, the Model Editor overwrites the
_editor.cmat
file as explained at Model Files Explained. In fact, we should never have hand-edited the_editor.cmat
file, but do all edits in.cmat
(without the_editor
part) instead, but we thought it’s too difficult to explain that in the video. 😉 Additionally, the Model Editor had to re-read the new material definitions anyway, so even if our edits were made in the right file, we had to close and reopen the model.
… scale my model?¶
There are two main methods for scaling a model:
- via the Skeleton / the Joint Inspector
- via the Transform dialog
The Joint Inspector can transform individual joints of the model, but only for the bind pose. It is mostly useful for static, non-animated models, but even then only if there is a special requirement that the Transform dialog cannot handle.
The Transform dialog is much easier to use, as it transforms the entire model (the whole skeleton): the transformation is applied to all currently selected animation sequences. If no animation sequence is selected at all, the “bind pose” is transformed.
… import animations from other models?¶
In some cases, importing animations is very easy: Use the “+” button in the Animations pane as demonstrated in the above video.
However, this works only if the animations are stored in separate files
that are compatible with the already loaded mesh. This is specifically
the case with md5anim
s for their related md5mesh
file.
We will extend this functionality in the future. Until then and for all other cases, see the next How-To about generically sharing and re-using elements.
Model Elements¶
Skeleton¶
The skeleton forms the basis of a model. Technically, it is built from a hierarchy of “coordinate systems”: Starting at the root, each coordinate system is defined in the coordinate system of its parent. Model artists use these coordinate systems to fix the points (weights and vertices) that eventually form the meshes of the model.
If we compare the skeleton of a model to the skeleton of the
human body, the “coordinate systems” closely correspond to “joints”: the
coordinate origin is in the center of the joint, and the coordinate axes
correspond to the bones that extend from the joint. In this analogy, a
“bone” is the line segment between a coordinate origin and the
coordinate origin of its parent system.
You can inspect the skeleton in 3D view in the Scene Setup:
- set Show Mesh to “no”
- set Show Skeleton to “yes”
The joints hierarchy¶
The Skeleton / Joints Hierarchy pane shows all the joints
in the skeleton, hierarchically arranged. Items in the hierarchy tree
can be expanded or collapsed with the nearby symbols.
A single click on a joint selects it, a double click opens the Joint Inspector pane as well.
The joint inspector¶
The Joint Inspector pane shows the details of the currently
selected joint.
General¶
The General section shows the name of the joint (it’s another option to rename it), and the index number of the parent joint.
The parent index number is a technical detail that cannot be changed. You need it only if you edit the model file in a text editor or work with the Cafu model C++ data structures.
Bind pose¶
This section shows the position, orientation and scale of the joint (i.e., the coordinate system).
Note that the details presented here only affect the bind pose of the model. The bind pose is the default pose of the model: it is used whenever no animation sequences are loaded or none are actively used.
That is, the Joint Inspector is great for manipulating the individual bones of static models.
It is however useless for animated models, because technically, each animation sequence brings its own set of (animated) joints that cannot be manipulated individually. If you want to do that, refer to Transforms: translate, rotate and scale instead.
The currently selected joint of the bind pose is described by these parameters:
- Pos
- defines the position of the coordinate origin relative to the parent system.
- Qtr
- defines the first three values of the quaternion that describes the orientation of the coordinate system. You should not attempt to manipulate these values if you don’t know what quaternions are and why it only shows three instead of four values.
- Scale
- expresses the scale (or relative length) of the three coordinate axes.
Meshes¶
The meshes define the shape of the model.
A model can have several meshes. Each mesh is made of triangles, whose vertices are composed of one or more weights, that in turn are attached to the Skeleton of the model.
Despite its name, it’s not the purpose of the Model Editor to modify the positions of weights and vertices, or to provide means to generally shape the meshes. Please see the The Model Editor: Introduction for more details. Instead, the Model Editor focuses on setting details that are specific to the Cafu Engine.
The meshes list¶
The Meshes pane lists all meshes in the model.
For each mesh,
- its name,
- the mesh number, and
- the mesh material (in the currently selected skin)
is shown.
A single click on a mesh selects it, a double click opens the Mesh Inspector pane as well.
Pressing the F2 key or a single-click on an already selected mesh allows you to rename the mesh in place.
The mesh inspector¶
The Mesh Inspector pane shows the details of the currently
selected mesh.
Name¶
Shows the name of the currently selected mesh. The name can be edited in order to rename the mesh.
Material¶
The material that is used for rendering the mesh is set here: Press the “…” button in order to open the Material Browser.
The Material Browser is the same as the one used in the Map
Editor, but it only shows the materials that are specific to the
currently loaded model. It also has some basic capabilities to edit
materials and to set their properties, but is currently not very
advanced.
At this time, we recommend that you use the Material Browser for assigning materials to meshes, but in order to create and edit material definitions, best use a programmers editor for editing the related cmat material files directly: Material scripting is documented in chapter The Cafu Material System.
(It is our goal to turn the Material Browser into a full-featured Material Editor in the near future, but we currently work on improving other parts of the Cafu code. If you want to lend a helping hand, please let us know!)
Tangent-space method¶
The tangent-space method determines the algorithm that is used for computing the normal, tangent and bi-tangent vectors at the vertices of the meshes.
Ideally, the algorithm that is set here should match the algorithm that was used by the external program that was used for creating the normal map for this mesh. This is important so that the Cafu model code can accurately reproduce the subtle details involved in generating the axes of tangent-space, as only then the lighting results will exactly match those in the original program. Unfortunately, the involved algorithms are not standardized at this time (and often not even documented!), so that we can only try a best guess.
Refer to CafuModelT::MeshT::TangentSpaceMethodT for the currently available tangent-space methods. More tangent-space methods will be added in the future.
If in doubt, there is a very simple receipt for choosing the right method: simply pick the one that looks best.
Cast shadows¶
This setting determines whether the mesh casts shadows when lit by a dynamic light source.
This can be useful for performance tuning, e.g. in order to not have shadows casts for very small meshes that implement model details, or generally for models that are very far away, or never seen in a context where shadows play a role.
Statistics¶
The last three numbers show the number of triangles, vertices and weights in the mesh. They cannot be changed.
Skins¶
Skins are used to apply alternative sets of materials to a model.
Typical examples are the butterfly model, where a single mesh is used with multiple skins to implement several species of butterflies; or a monster that exists in tame, mean and hellborn variants.
Skins are defined and edited in the Model Editor as described below. The use of skins is up to the game’s script or C++ code.
The skins list¶
The Skins pane lists all skins in the model.
For each skin,
- its name and
- the skin number
is shown.
A single click on a skin selects it, a double click opens the Skin Inspector pane as well.
Pressing the F2 key or a single-click on an already selected skin allows you to rename the skin in place.
The skin inspector¶
Skins don’t have explicit properties of their own, thus the
Skin Inspector pane is just a help dialog that explains the
situation:
GUI Fixtures¶
GUIs are virtual computer desktops that the player can interact
with to unlock doors, call lifts, obtain information, and much more.
The GUI fixtures list¶
The GUI Fixtures pane lists all GUI fixtures in the model.
For each GUI fixture,
- its name and
- the GUI fixture number
is shown.
A single click on a GUI fixture selects it, a double click opens the GUI Fixture Inspector pane as well.
Pressing the F2 key or a single-click on an already selected GUI fixture allows you to rename the GUI fixture in place.
The GUI fixture inspector¶
The GUI Fixture Inspector pane shows the details of the
currently selected GUI fixture.
Name¶
Shows the name of the currently selected GUI fixture. The name can be edited in order to rename the GUI fixture.
Origin and endpoints¶
The origin and the endpoints of the x- and y-axes determine the position and orientation of the GUI.
You can enter and edit the mesh and vertex numbers manually, but it is much easier and faster to right-click directly on the model in the 3D view:
Selecting one of the three GUI fixture menu items will fill in the related numbers in the GUI Fixture Inspector automatically.
Translation and scale¶
Normally, the GUI rectangle is exactly aligned to the origin and the endpoints of the axes. Using the translation and scale, you can move the GUI rectangle from its original position and adjust its overall size:
- The Scale values set the relative lengths of the axes.
- The Translation values move the origin in multiples of the scaled axes.
Example video¶
This video shows a GUI that is attached to an animated model and uses custom translation and scale settings.
Animations¶
For many models, animations are the most noticeable and most important feature: Animation sequences define how a model moves, behaves or transforms over a period of time.
Animation sequences, like the model itself, are typically created by the model artist before the model is imported into the Model Editor.
The animations list¶
The Animations pane lists all animation sequences in the
model.
For each animation sequence,
- its name and
- the sequence number
is shown.
A single click on an animation sequence selects it, a double click opens the Animation Inspector pane as well.
Pressing the F2 key or a single-click on an already selected animation sequence allows you to rename the sequence in place.
.md5anim
file) and adds it to the list. The “-” button
deletes the currently selected animation sequences.The animation inspector¶
The Animation Inspector pane shows the details of the
currently selected animation sequence.
Name¶
Shows the name of the currently selected animation sequence. The name can be edited in order to rename the sequence.
FPS¶
The speed in frames-per-second with which this animation sequence is played.
It’s normally set by the model artists and needs only be changed e.g. for special effects such as slow motion, or if the right number was not correctly imported from the original model file, etc.
Num Frames¶
The number of key frames that the sequence consists of. The key frames are created by the model artist and cannot be changed here.
Next sequence¶
This is the number of the animation sequence to play after the current sequence.
This value is set to -1 to indicate “no” next sequence, which is used for animations that should just stop when they’ve reached their last frame. For example, a sequence of a player model for dropping to the ground after it was mortally wounded typically has a next sequence value of -1, indicating that this is a “non-looping” sequence.
Setting the value to the same number as the number of this sequence means “play this sequence again when its end has been reached”. It’s another way of saying that this is a looping sequence, such as walking or running.
Setting the value to a number other than -1 (“non-looping”) or the own sequence number (“looping”) can be useful to indicate logically consecutive sequences. For example, if a player model has a sequence for holstering its weapon, the “next sequence” value might be the number of an idle sequence – whatever the player does after he has the hands free.
Channels¶
Channels are used for grouping joints. They allow animations to play only on a subset of the model joints, so that multiple animations can play on different parts of the model at the same time.
For example, you can play a walking animation on the legs, an animation for swinging the arms on the upper body, and an animation for moving the eyes on the head.
Animation channels are defined and inspected in the Model Editor as described below. The use of channels is up to the game’s script or C++ code.
The channels list¶
The Channels pane lists all animation channels in the
model.
For each channel,
- its name and
- the channel number
is shown.
A single click on a channel selects it, a double click opens the Channel Inspector pane as well.
Pressing the F2 key or a single-click on an already selected channel allows you to rename the channel in place.
The channel inspector¶
The Channel Inspector pane shows the details of the
currently selected channel.
Name¶
Shows the name of the currently selected animation channel. The name can be edited in order to rename the channel.
Joints¶
Select for each individual joint whether it will be a member of the channel.
Program Dialogs¶
Scene Setup¶
One of the Model Editor’s main fields of application is to let you visually inspect the model as rendered by the Cafu Engine and as it will appear in the game.
For this purpose, the Scene Setup dialog lets you change the details on how the Model Editor renders the model in the 3D view. Refer to section The Main Window for more information about the 3D view itself.
General¶
- Background Color
- sets the “sky” or background color. Future versions of the Model Editor will allow to load cube maps for proper sky environment rendering as well.
- Show Origin
- determines whether the principle axes of model space, emanating from the origin, are shown.
- Show Grid
- , when selected, renders a spatial coordinate grid, centered at the origin.
- Grid Spacing
- sets the spacing between grid lines.
Camera¶
Camera attributes are rarely entered manually: Normally, you navigate the 3D view as described at section The Main Window, and the camera details update automatically.
- Pos shows the x-, y- and z-coordinates of the camera position.
- Angles shows the orientation of the camera as angles for Pitch and Yaw.
- The Advanced settings control the shape of the camera’s view frustum: vertical FOV is the vertical field-of-view, and near/far plane dist is the distance of the near/far clipping plane relative to the cameras position.
Scene Elements¶
Ground Plane¶
- Show
- determines if the ground plane is shown at all.
- Height (z-Pos)
- sets the z-position of the ground surface.
- Auto Height
- , if set, automatically adjusts the z-position of the ground surface to the dimensions of the model.
- Material
- sets the material that is used to render the ground plane.
Model¶
- Show Meshes
- determines whether the meshes of the model are rendered.
- Show Skeleton
- , if activated, renders the joints and the “bones” of the model.
- Show triangle normals
- , if activated, renders the normal vector of each triangle. The color of the normal vector indicates the Polarity of the triangle.
- Show tangent-space
- , if activated, renders the axes of tangent space at each vertex of each mesh.
- Debug material
- allows to override the mesh materials of the currently selected skin with “debug” materials that facilitate the inspection of the model: plain (white) is useful for inspecting the shades resulting from lighting, wire-frame shows the individual triangles that the meshes are composed of.
Animation Control¶
- Frame No.
- is the frame number in the currently playing sequence. It advances automatically if an animation is playing, but can be set manually as well.
- Speed
- is the relative speed with which the animation is currently playing. It’s automatically set to 0 or 1 if you press the Play or Pause buttons in the toolbar.
- Loop
- , if set, forces the Model Editor to play the current animation in an infinite loop.
Light Sources¶
- Ambient Light Color
- is the color of the ambient light. Ambient light is also there when all other light sources have been turned off.
- Light 1, 2, 3
are dynamic light sources as they can also be set in the Map Editor and occur in the game:
- On
- determines whether the light source is on or off.
- Cast Shadows
- sets if the light source casts shadows at all.
- Pos
- the position of the light source.
- Radius
- the radius of the light source.
- Color
- the color of the light source.
Submodels¶
Submodels are models whose skeleton is (partially) aligned to the skeleton of their parent model.
The most prominent examples for submodels are weapon models that are combined with player models: Each player model can be combined with any weapon model, and the animation sequences of either combine naturally with each other:
It’s typically the job of the game code to load and combine parent models with their submodels, but the Model Editor implements this feature as well so that you can inspect loaded submodels easily:
Press the “+” button in the Submodels dialog in order to load a new submodel.
In theory, you can load more than one submodel per parent model, although that only makes sense if you load e.g. different weapon models for the left and right hands of the player, or child monsters that are carried in different locations in the parent monster, etc.
The “-” button unloads the selected submodels again.
Level-of-Detail Models¶
Level-of-detail models are a kind of “meta” models: They consist of two or more “normal” models, but only one of the referenced models is shown at any time, depending on the distance to the viewer.
The key idea is to render a detailed model only when the player
(the camera) is close to it. When the camera gets farther away, a less
detailed model is rendered. And when the camera gets even farther away,
an even less detailed model is used.
This technique, while not without its downsides, is a common approach for reducing the computational effort required for rendering a model relative to the amount of detail that the player can perceive of distant objects.
Loading LoD models¶
Level-of-detail models have a file suffix of
.dlod
, and you
open them in the Model Editor like .cmdl
models or any other model
files.
The Level-of-Detail Models dialog will show the list of “real” models that the LoD model is referring to, and up to which viewer distance each model is used.
Inspecting and saving LoD models¶
In the list and inspector panes, the Model Editor will only show the elements of the first (closest, most detailed) referenced model, even if the camera is moved far enough away so that in the 3D view one of the lower detailed models is rendered.
If you attempt to save a .dlod
model, the saved file will be the
first referenced model as well. That is, it will be treated like an
individual, independent model, not as the whole set of models in the
.dlod
file.
As a result, you should load LoD models only for inspecting them in the
3D view. In order to edit the component models the .dlod
file is
referring to, you should load them directly by their true name, each one
separately from the other.
Creating LoD models¶
.dlod
files cannot be created in the Model Editor. They are simple
text files that you have to create yourself, using a programmers text
editor.
Here is an example, taken from
Games/DeathMatch/Models/Static/TonneTest.dlod
:
TonneTest_LoD1.ase 10000
TonneTest_LoD2.ase 20000
TonneTest_LoD3.ase 40000
TonneTest_LoD4.ase 80000
TonneTest_LoD5.ase
Each line lists a concrete model and the distance up to which the model is rendered.
- The distance for the last, farthest model is optional. If given, it is ignored: the last model is used up to infinity.
- The file names are relative to the path of the parent (
.dlod
) file. Valid examples includea/x.cmdl
and..\y.ase
, whereasc:\z.mdl
is invalid. - The numbers are given in Cafu world units (which are currently not the same as CaWE world units: they are only 1/25.4 of the Cafu units!). In Cafu worlds, each unit is 1 millimeter. 1000 units are one meter or 3.2808 feet.
- In many ways, the first model in the list is “responsible” for the collective: The Cafu Engine gets the bounding boxes, number of animation sequences etc. all from the first model. Ideally though, all models should have the same BB, same (logical) animation sequences, etc.
An example¶
The image below shows three models, a simple barrel. The three models are independent of each other, and each is stored in a separate model file. They all implement the same logical object though, each at a different level-of-detail:
Combine models like these in .dlod
files as shown above – that’s
all! Your LoD model is now immediately available for use in the Map
Editor and the Cafu Engine.
Transforms: translate, rotate and scale¶
The Model Transform dialog is used to translate, rotate or
scale the entire model.
It is opened
- via menu item Model → Transform… (Ctrl+T),
- or the “Transform” button in the application toolbar.
Contrary to the Joint Inspector, the Model Transform dialog can not be used to transform individual joints in a skeleton, a feature that is only useful for static, non-animated models.
The virtue of the Model Transform dialog is that it affects the entire model (the whole skeleton), and that the transformation is applied to all currently selected animation sequences. If no animation sequence is selected at all, the default pose (also called the “bind pose”) is transformed.
Purpose¶
The Model Transform dialog’s main area of application is to adjust newly imported models to the Cafu coordinate system:
An authoring program might have exported a model in a scale or default orientation that does not agree well with the Cafu coordinate system, or just is different from other models that you already have.
Use the Model Transform dialog to fix such and similar cases easily.
Model Files Explained¶
Each model comprises several files on disk, such as the model file, material definition files, and texture images.
When you save a model in the Model Editor, the editor creates or re-creates some of these files, updates others, and leaves alone the rest. The result is normally exactly what you want and expect, but sometimes you may wish to hand-tune some details (such as the material definitions) without and independently of the Model Editor. In such cases, it is very helpful to understand the files that belong to a model.
This section explains the files that together form a model and how they relate to each other.
One directory per model¶
Although not a technical requirement and not enforced by the Cafu model code, it is highly recommended to save each model in a directory of its own. This
- explicitly groups all files that logically form and belong to the model, and
- makes packaging a complete model in a
my_model.zip
archive possible, so that the model can easily and safely be distributed, shipped and handled.
The name of the directory should match the file name of the model. That
is, if your model’s name is Trinity.cmdl
, it should be stored in a
directory with the same name Trinity/
(or in a zip archive with the
same base name Trinity.zip
).
Note that when you are saving a new model that does not yet have a separate directory, you can use the “New Folder” button (or right-click context menu) of the “Save” dialog to create such new directories as required.
Example:
d:\Dev\Cafu\Games\DeathMatch\Models\Players> dir Trinity
ChromeBuckle_diff.png
ChromeGlass_diff.png
Pants_diff.png
Skin_diff.png
Trinity.cmat
Trinity.cmdl
Trinity.cmdl_bak
Trinity_editor.cmat
cmdl model files¶
The cmdl
file is the main file of the model: It contains the
definitions for the skeleton, the meshes and the animation sequences of
the model.
The Cafu Engine and the Model Editor load cmdl
files as
Lua scripts, and as such they can be inspected
or edited in a text editor if desired.
Besides the main cmdl
file, the Model Editor also creates a
cmdl_bak
backup file that contains the contents of the cmdl
file
before it was last saved. (If you ship your model as a zip
archive,
the cmdl_bak
file is typically redundant and can be omitted from the
archive for space efficiency.)
Example:
d:\Dev\Cafu\Games\DeathMatch\Models\Players> dir Trinity\*.cmdl*
Trinity.cmdl
Trinity.cmdl_bak
cmat material definition files¶
The cmat
files contain the material definitions for the meshes of
this model.
The main cmat
file must have the same base name as the model
(“Trinity”), so that the full name is for example Trinity.cmat
. This
file is for your hand-written material script code, if any, and is never
touched or overwritten by the Model Editor (with one exception, see
below).
The Model Editor also writes a secondary cmat
file whose name ends
with _editor.cmat
. This file is written anew each time the model is
saved, and contains material definitions whose script code was not
hand-crafted, but who were created or edited in the Model Editor.
Example:
d:\Dev\Cafu\Games\DeathMatch\Models\Players> dir Trinity\*.cmat
Trinity.cmat
Trinity_editor.cmat
The two cmat
files are linked as follows: When the Cafu model code
loads the materials of a model, it opens the main cmat
file
(Trinity.cmat
). This file contains a statement like
dofile("Trinity_editor.cmat");
in order to include and process the secondary _editor.cmat
along
with the main file.
The only exception when the Model Editor touches the main
Trinity.cmat
file is when the file does not yet exist, or doesn’t
contain the dofile()
reference to the editor file. In this case, the
_editor.cmat
would not be loaded at all, and thus the Model Editor
inserts the dofile()
line into the main cmat
file.
In summary, the goal of keeping two separate cmat
files that are
linked as described above is to keep your hand-crafted material script
code and the Model Editor edited material definitions cleanly separated,
without any danger of one overwriting the other.
Texture images¶
The texture images are referenced from the material definition scripts. See the documentation about the Cafu Material System for more details.
Example:
d:\Dev\Cafu\Games\DeathMatch\Models\Players> dir Trinity\*.png Trinity\*.jpg
ChromeBuckle_diff.png
ChromeGlass_diff.png
Pants_diff.png
Skin_diff.png
Dependencies among Models¶
Although it might not be obvious at a first glance, there are several dependencies among certain models. It is worthwhile to have knowledge about these issues before you start making own models, because it helps with resource planning and prevents expensive problems later.
We’ll describe several typical kinds of dependencies, considering the example of the Cafu DeathMatch MOD: In the Cafu DeathMatch MOD, mutual dependencies affect the human player models and their weapons.
First, lets deal with all “other” models, i.e. those that are neither player nor weapon models: Usually, these other models are not closely related to each other, each of them has a separate piece of game code associated that handles it, and thus they do not suffer from any inherent dependency problems.
Human player models¶
Human player models are special, because they are usually intended to be 100% equivalent to each other. That is, if somebody makes a new human player model and offers it for download, you expect it to work exactly like the ones that you already know. In order to achieve this kind of equivalence, two assumptions must hold: The skeleton of the new models must basically match the skeleton of the old models, and the animation sequence numbers must refer to reasonably identical animations.
The animation sequences must match, because the game code has built-in knowledge that, for example, sequence number 3 refers to an “idle (waiting)” animation, and that sequence number 27 refers to an “aiming with a shotgun” animation. It is entirely up to you to animate your model to look at his wrist watch while aiming with the shotgun, or to pick his nose, but it is important that sequence number 27 corresponds to some “aiming with a shotgun” animation – because the same is true for all other models, and the game code relies on it.
The skeletons must also match, for similar reasons: At least the basic hierarchical structure (starting from the pelvis to the most important bones) must be identical, as well as the names(!) of the corresponding bones. However, you are free to add bones to the skeleton as you like, change their sizes or lengths, change their positions relative to each other, and do many other interesting things. You may even omit bones if you want to create a one-armed, one-legged hero. What works and what works not is easiest determined by trying it out, but please do also refer to the next part about weapons.
Weapons¶
Weapons do usually come as a set of three models: “world” models, “player” models, and “view” models.
World models are the models that lie around in the world, before someone picked them up. They are usually not animated (or only have a single animation sequence), are independent from anything else, and are therefore in the same category as the “all others” models, so that we need not be further concerned about them.
Player models are the weapons that you see in the hands of other
players who have picked up and are using that weapon. For the following
discussion, we’ll refer to the “player” weapon model as the “_p
”
model, and to the character model of a human player as the “body” model.
First, if you consider the skeleton of a _p
model in the Model
Editor, you will find that it resembles a partial body model (the bones
from the pelvis to the shooting arm are there!), before it diverges into
additional bones for the actual weapon.
Here is the crucial point: In order for the engine to compute the proper
position of the _p
model relative to the body model, it (partially)
has to match the skeletons of both models! That is, it first computes
the skeleton of the body model (depending on its current animation
pose). Then it considers the skeleton of the _p
model, starting at
its root, and tries to match it bone-by-bone to the previously computed
body skeleton. If a match was found, the engine simply takes the
information from the body model bone also for the _p
model bone.
Only when the matching breaks for the first time, the engine resumes
normal bone computing also for the _p
model. (This way you can for
example see a face-hugger in the hands of another player that is
wagging it’s tail.) Matches are made by comparing the names of the
concerned bones.
As a consequence, if you want to make additional body models for the DeathMatch MOD, and additional weapons, and you want to be able to combine each body model with each weapon, then you have to make sure that theyallhave a corresponding skeletal structure and bone names!
View models are the models that you see in 1st persons view after you have picked up a weapon yourself. They are also independent from anything else, but the game has usually special code for handling them. Thus, you can well make a replacement weapon for e.g. the shotgun, matching the animation sequences of the existing “view” weapon model according to similar rules as indicated for making replacement human player models. You can also introduce entirely new weapon models, but be prepared that is requires to augment the game’s C++ or script code as well.
Applicability to your own game¶
If you create an own game, things may or may not be different, of course. However, keep in mind that if you want to achieve a high degree of flexibility and ease of maintenance, you’ll sooner or later probably experience the same rules and dependencies as described here. They are the – relatively cheap – price for the ability to combine every human player model with every weapon model.
Supported file formats¶
The Cafu engine currently supports 4 different image file formats: .jpg, .png, .tga and .bmp. This documentation shows you the advantages/disadvantages of those file formats.
.png file format: The .png file format is the optimal file format for Cafu! It can feature transparent parts that allows them to be used for textures that have invisible parts (like windows). Advantage: The transparent parts can be created very easily with image editing software. There is NO loss of quality at all with this compression - optimal for high detailed textures. Disadvantage: They are bigger in the size than jpg on the hard drive.
.jpg file format: The .jpg image format is very small in size on the hard drive because of it’s compression. jpg-files can be used for diffuse maps - but with care - dont compress them too much! The disadvantages are that they can’t handle transparent parts, which makes them unusable for some tasks and the compression leads to a loss of quality. Don’t use it for high frequency textures!
.tga file format: The .tga file format is like the .png format - the only difference is the size - tga files are bigger in size on the hard drive than png!
.bmp file format: This file format is very large in size and can’t feature transparent parts. It’s advantage is it’s quality - there is no loss of informations when saving into this format!
Summary: Use png files whenever it’s possible. The alternative for textures without alpha channles is bmp, for those with it’s tga. Try to avoid jpg for high frequency textures and normal-maps!
Texture types¶

In almost all cases, you start making a new material with the diffuse-map. Diffuse-maps are almost always created manually in an image processing program, e.g. hand-painted or delivered from a photograph, similar to the way “old-style” textures were made in the past. The diffuse-map shows material color when the surface is diffusely lit. Thus, you should not draw any hard shadows into the diffuse-map - they are automatically created by the engine later from the information that comes from the normal-map and the light sources. You may however, in some cases, draw some soft shadows into the diffuse map, a sort of “reachability factor” (“How hard is it for the light to reach a certain spot on the texture?”). This implies that a diffuse-map that shows for example corrugated metal or a rough rock surface could be an image that only has a single shade of grey! Also note that the final material when rendered by the engine tends to look best when you use pixel values of medium brightness. Moreover, high-contrast and high-frequency components should be used with care in diffuse-maps, as such components often interfere with normal-maps later, compromizing the effect of dynamic lightning. Also the specular highlights might look strange with such diffuse-maps.
Specular-maps (sometimes also called gloss-maps) define the shininess of the material. They are conveniently created together with or derived from their diffuse-map. Bright values mean that the material is very shiny, dark values mean that the material is mat. Note that specular-maps are not limited to gray-scaled images: Their tone (color) modulates with the color of the light source. Specular-maps often have the strongest impact on dynamic lightning. Note that for many materials that only have diffuse light reflection characteristics (e.g. sandstone), specular-maps can often be omitted entirely.
Luminance-maps define the light that a texture emits. As with specular-maps, they are easiest created together with their diffuse-map, and often very simple in nature. The light of luminance-maps is local to the texture, and does not cast on any other surfaces or objects. Typical occurances for luminance-maps are with LED panels or computer-screens, but frequently they are not present at all, because most materials do not actively emit light themselves.
Height-maps (also called bump-maps) are gray-scale images that define the height of a surface: dark is low and white is high. They often only serve as an intermediate product for creating normal-maps. In fact, Cafu converts all height-maps to normal-maps internally before use. Some people convert the diffuse-maps to gray-scale images in order to obtain height-maps, but this does almost always yield in bad quality - this is just a lazy trick that one should never use. Instead, height-maps should be painted or created from scratch. This is almost always a very difficult task though, and works best with either natural or organic materials or high-frequency components like scratches, dents, and so on. Another method is to obtain height-maps from the depth buffer information of some rendered geometry. In this case, however, I’d recommend to skip height-maps entirely, and render normal-maps directly.
Normal-maps are the most important component in dynamic lightning. They contain information about the shape of the surface by color-encoding the surfaces normal vectors. They are normally never hand-made, but either derived from height-maps or created from true 3D geometry. For example, plug-ins for Photoshop as well as for TheGimp exist for converting a height-map into a normal-map. For normal-maps that represent technical features like the example panel above, the best results are achieved by creating them from 3D geometry though, which for example is possible with 3D Studio Max. Please note that combining diffuse-maps and normal-maps that both have high-frequency components (and the diffuse-map possibly highly contrasting colors) tends to compromize the effect of dynamic lightning.
Skybox creation (Environmental Map, Cubemap)¶
A skybox is a special set of textures that is used to display the sky. Cafu uses skyboxes to create skies. A skybox consists of 6 textures. Try to imagine a map that is surrounded by a box. The walls are covered with the sky textures. Sky + box = Skybox ;)
This documentation focuses at first on the integration process into Cafu and displays later, how to create a skybox in general!
Here is an example of what those 6 sky textures can look like. If you have some knowledge in geometry, you’ll notice that the textures are in this example put next to each other in form of an unfolded cube to demonstrate how this skybox system works.
(Click on the picture to enlarge it)
How to integrate a skybox into Cafu¶
The textures can have the dimensions 256×256, 512×512 and 1024×1024 (other dimensions don’t work or don’t make sense). It is important that they are seamless when being put together, otherwhise you have viual glitches ingame.
If you have a close look at the picture, you can see that it includes the names of the textures. As you can see, their names begin with sky1 but end with keys like _py. The endings tell the engine which texture demonstrates which site, sky1 is just the name of the sky used in this tutorial. Like this, it is important to name your textures right. Here is a small overview about which ending stands for which direction:
(FIXME!) This passage needs to be filled with content
- _nz :
- _nx :
- _pz :
- _px :
- _py : The upper side
- _ny : The lower side
Once named your sky textures right, you can place them in the skybox directory that can be find in the textures directory.
Then, you have to create a shader file for the sky. If you don’t know what a shader is, please have a look at this desciption.
In the case you named your sky sky1, the shader file would look similar to this:
Textures/SkyDomes/sky1
{
AmbientShader A_SkyDome
LightShader none // == noDynLight keyword
// The '#' in the next line is auto-replaced with the relevant suffixes (_px, _ny, ...).
cubeMap Textures/SkyDomes/sky1#.jpg, wrapS clampToEdge, wrapT clampToEdge
ambientMask d // Don't write into the z-Buffer, so that entities (like missiles) outside of the map can still be drawn.
noShadows // This material does not cast dynamic shadows.
meta_noLightMap // Don't create or keep lightmaps for this material, don't participate in Radiosity computations.
meta_sunlight // This keyword states that this material casts sunlight.
( 2 4 6) // The irradiance of the sunlight in Watt/m^2 that comes (or shines) through this material. Values (100 90 80) might work, too.
(-2 -5 -9) // The direction of the incoming sunlight rays. The z-component should be negative. These values match the actual position of the sun in the cube-maps.
}
Basically, line 1, 7, 13 and 14 are important.
- In line 1, you have the textures path for CaWE, basiacally you just have to change sky1 into your sky name.
- In line 7, you have to change the path so the sky name (in this case sky1) is right and the texture format (in this case .jpg).
- In line 13, the shader defines the colour of the sunlight (there’s a description for this values later in the tutorial).
- In line 14, the shader defines where the sun is in the sky (important for light calculation in maps, a descriptions can be found later in this tutorial).
When finished, save your cmat shader file and you can find your sky in CaWE. Note: the first line of the shader (Textures/SkyDomes/sky1) is also the name of the sky in CaWE.
That’s it!
The irradiance of the sunlight¶
(FIXME!) This passage needs to be filled with content
The direction of the sunlight¶
(FIXME!) This passage needs to be filled with content
How to create a skybox with Terragen¶
Terragen is a terrain generator that can also create skyboxes. The skyboxes included in Cafu were created with Terragen. There are various resources in the internet that cover skybox creation with Terragen. Here are some recommended links:
How to create a skybox out of photos¶
(FIXME!) This passage needs to be filled with content
How to create a skybox out of panoramic images¶
(FIXME!) This passage needs to be filled with content
Using own textures¶
This tutorial has 3 part. The first part covers textures for maps, the second part covers skins for models and the third part skybox textures.
Part 1: Map textures¶
Create your texture. Then save it into one of the supported file formats (those are: .jpg, .png, .tga, .bmp).
Go into your Cafu directory and from there into the textures directory: Games → DeathMatch → Textures. There it should somehow look like this:
Now create a new directory, I call mine “tutorial”. Go into it and place your texture there. I call my texture “texture1”, it consists of a diffuse map, a normal map and a specular map. I add endings to the different textures to exactly know which texture is which type. My diffuse maps have a _diff tag in their name, normal maps get _norm, specular maps get _spec and luminance maps _lum (not necessary to give them those tags though).
OK, that was the first half, what we now have to to is to write a so called “shader” file, a text file including names and paths of textures that gives the informations about the textures, e.g. if they have normal maps and so on or if they have transparent parts.
Let’s go back to the DeathMatch directory. There you can find the “Materials” directory in which all shader files are placed. They can be opened with simple text editors like notepad. If you open for example the “generic.cmat” file, you can see that it contains informations about various textures. The system works like this:
Textures/directory_name(in which the textures are palced)/texture name
{
type_of_texture Textures/directory_name/texture_patch
}
The best way to describe those shaders is to actually have a look at them. Here is the shader for my texture:
Textures/tutorial/texture1
{
diffusemap Textures/tutorial/texture1_diff.jpg
normalmap Textures/tutorial/texture1_norm.jpg
specularmap Textures/tutorial/texture1_spec.jpg
lightmap $lightmap
}
If you have a luminance map you would have to write “lumamap” (without quotes).
It’s easy, isn’t it? And that’s already it! You can save it as yourshadername.cmat or within another shader and it will work. Start your mapping editor and you will be able to use the texture!
Download: Tutorial example files (.zip file) Download: Tutorial example files (.tar.gz file)
Part 2: Model textures¶
Using own skins (model texures) is as easy as using map textures. There are only slight differences.
Instead of being placed in a directory in the textures directory, you have to place them in one of the directories in the Models (like the models themselves) directory. Let’s say we place them into the Static directory that is placed in the Models directory. Our shader-file has to be placed in the Models directory that can be found in the Materials directory. It would look like this:
Models/Static/mymodelname/a_name_for_my_skin
{
diffusemap Models/Static/a_name_of_my_skin_diff.png
normalmap Models/Static/a_name_of_my_skin_norm.png
specularmap Models/Static/a_name_of_my_skin_spec.png
red ambientLightRed
green ambientLightGreen
blue ambientLightBlue
}
There are only small differences: 1. you have to add a model name too and not only a texture name (“mymodelname/a_name_for_my_skin”) - note that you can choose whatever you want, those names dont have to meet the model name/texture name. 2. in the lower part you can see that you have to add those red, green and blue informations
Well that’s it! If there are questions, feel free to post them in the forums!
Part 3: Skybox textures¶
You can find detailed tutorial concerning the integration of new skyboxes here:
Making “perfect” Detail-Maps¶
The Problem¶
Detail-maps, in order to work well, must meet two requirements:
- Their average value must be 128 (50%) so that they don’t change the total brightness of the texture they’ll be applied to, and
- they must not show tile patterns when they are minified (e.g. when they’re viewed from a great distance).
Getting 1. right is the task of the artist, and is easily done in any paint program that supports contrast and brightness adjustments and histogram views.
This screenshot shows the effect
of applying the detail-map to a large terrain. Note the well-visible
pattern both on the near ground as well as on the far rocks. This strong
pattern is caused by the non-balancedness of the detail texture.
The Idea¶
The Solution¶
First, observe that E is easily found by blurring a copy of D! Any paint program can easily do that! I used The Gimp to apply a Gaussian blur filter to the detail map, creating test images with filter widths of 5, 20, 40 and 60 pixels respectively. The left image below shows my so obtained “E”, which is the original detail-map blurred with a 60 pixels width Gauss filter!
The next problem is that computing the above D - E + 128 has a tendency to produce intermediate values that are less than 0 or greater than 255. Therefore, this operation can not be done with layer techniques in PhotoShop, PaintShop, Gimp, etc.!
In order to get correct results easily, I just wrote a small C++ program that reads E and D from two images files on disk, computes D - E + 128, and writes the result back into a third file. Please send me an email if you’re interested in the exe file for Windows!
And yes, that’s all! I applied my program to the above detail-map D and it’s error-map E (left image below). The center image below shows the result. Notice how beautifully the dark spot is gone! In the right image you see a screenshot of the same scene as above, now with the new detail-map being applied. Note that the pattern is (almost) entirely gone!
Also please note that now you see a new “pattern” at the mountains – this is the result of a not-so-good base texture that is showing up now that the broken pattern of the detail-map has been fixed and does not any longer distract from it. This matter is not related to detail-map issues, and is just fixed by using a better base texture.
Discussion and Results¶
One open question is how much D should be blurred in order to obtain E. This is easily answered: As much as possible! In the above example, I used a blur filter of 60 pixels width, and the pattern as (almost) completely gone. Using smaller filter sizes reduces the rests even further. For example, I also made tests with blur filters of 5, 20 and 40 pixels width. The smaller the filter kernel width was, the more homogeneous became the end result. (Blurring not at all obviously yields the 128 planar detail map (because then E=D, and D-D+128 = 128) and has no visual impact at all!)
Therefore, the recommended strategy is to start with a really big amount of blurring, and only reduce it if that amount was not sufficient to remove the most significant non-balancedness of the original detail-map.
High-Pass Filters in PhotoShop¶
After I had completed this article, Kai sent me a link to this Gamasutra site: http://www.gamasutra.com/features/20010523/hajba_01.htm It deals with the same problem and is a lot more detailed than this text – definitively a recommended read! As the solution, High-Pass Filters are presented which achieve exactly the same results and which are – contrary to my above statements – well built into PhotoShop and possibly other paint programs, too. So if you’re a dedicated user of your favourite paint program, you’ll probably want to give the built-in high-pass filter a try before trying my home-grown solution. 😉
What is it? An Introduction¶
The Cafu Material System is the central rendering subsytem of the Cafu engine and its graphical tools like CaWE, the model viewer, the terrain viewer, and so on. It takes polygonal meshes of geometry and renders them on the screen. While doing so, it is responsible for the materials that the mesh surfaces show. Said differently, it defines how the rendered polygons look.
The Material System is not involved with or responsible for what gets rendered, when it is rendered, how the meshes are spatially formed or organized, etc.
Purpose, Goals and Features¶
The introduction of the Cafu Material System solved incredibly many problems and comes with equally many advantages. Some of them are hard to explain and/or hard to grasp, but here is a (partial) list anyway:
- Unique rendering across all programs: The Cafu engine, CaWE, the model viewer, the terrain viewer, the material viewer, … all use the same rendering code and technology. I was finding myself writing, debugging and synchronizing the same code over and over again, for each mentioned program and for each supported 3D API, multiplying the expenses until chaos. This was one of the main reasons to start the MatSys. The savings are enormous, and I can be sure that models in the model viewer are rendered 100% identical as in CaWE or the engine.
- Unique rendering across all types of geometry: Worse than the above, I found myself implementing the same technology even several times in the same program: once for the models, once for the world polygons, once for the terrains, etc. Sharing global resources like textures or GPU programs was impossible, and the Cafu engine happended to render the world polygons with different technology than the models, the terrrains with a third, and so on. Debugging was a nightmare. That’s all over now, everything is now handled by the MatSys, and the savings and the leap in improved code-design were huge.
- Can easily add support for new platforms, operating system, APIs. Without any danger to break existing code, and even without having to touch existing code at all, new renderers and new shaders can be introduced: If hot-plugging a new graphics board into your computer was possible, the Cafu engine could handle that situation while running. You can even supply and use a completely new renderer without stopping or recompiling the executables. Just have the engine reload the renderer, and the new technology will be immediately used.
- Users and artists get a much greater and more flexible control over the rendering, as all materials can be edited independently from the worlds or models that they are applied to.
Renderers¶
The MatSys is shipped in several separate modules. Each module offers the same features, but they are different in that the implementation of each is based on a different underlying technology. These modules are called the Renderers of the Cafu MatSys. For example, a MatSys renderer exists that is based on OpenGL 1.2, another is based on the latest programmable GPU features and others are somewhere in the middle. In fact, Cafu ships with several of them, and it uses the MatSys by actually employing one of the renderers.
Technically, renderers are dynamically loaded libraries (.dll
files
on Windows systems), and you can find them in the Renderers/
subdirectory of the demo or SDK. When the Cafu engine or another program
starts, it first scans the list of all available renderers,
automatically determines the one that is the best (or most appropriate)
for your system, and then loads it (this specific instance of the
Material System) for use.
This way it does not matter wether your computer is very old or the latest leading-edge system, wether it uses OpenGL, Direct3D or software-only rendering or wether its OS is Windows or Linux: You always get the best possible graphical output – this is one of the goals the MatSys has been designed for!
Materials¶
Materials define what surfaces look like and what features a surface has, and if you are interested in Cafu editing, you’ll most likely get in touch with them.
For example, mappers assign materials to world geometry in order to give all objects the look and feel that they want. Modellers often create new materials for the creatures that they create, and then assign them to the polygonal meshes of their model.
When it comes to rendering, the Cafu engine takes both the meshes and their assigned materials, and hands them to the Material System. The MatSys then does it’s best to render the mesh with that material as accurately as possible on the available technology.
Each material is referred to by its name, and is defined in a material
definition script file. These files have the suffix .cmat
and can
contain the definition of one or more materials. They are simple ASCII
text files, and you can find many examples in the
Games/DeathMatch/Materials/
subdirectory of the demo or SDK.
Here is an example of a material definition from
Games/DeathMatch/Materials/Kai.cmat
:
Textures/Kai/3r_metpan01
{
diffusemap Textures/Kai/3r_metpan01_diff.png
normalmap Textures/Kai/3r_metpan01_norm.png
specularmap Textures/Kai/3r_metpan01_spec.png
lightmap $lightmap
}
Using materials is very easy. For example, when you’re mapping with CaWE, you apply materials to world brushes in the same way as well-known textures used to be applied in other or older map editors, too. Please see the CaWE User Guide in this Wiki for more information.
Creating materials often requires two steps: You first have to create
or acquire the texture maps that are used or required by the material.
These are typically png, jpg or tga images that define the diffuse-,
normal-, specular-, and other component maps that will be referred to by
the material. Then you have to write a material definition into a
.cmat
script file like in the example above. Very advanced materials
may also involve a third step, namely in the case that they require
their own unique shader (see below). The documentation in this Wiki has
detailed documentation about each of these steps.
Shaders¶
The meaning of the word Shaders in the context of the MatSys is a bit different than its meaning in other contexts (the word “shader” has many meanings, after all). Shaders are objects of C++ code, and each renderer has several of them built-in (in some cases up to a few dozens). Most people will therefore never be faced with one of them.
However, shaders are the final instance in rendering, they define exactly how the looks of a certain material is achieved. Therefore, when the MatSys is given a certain material, it consults its library of built-in shaders and selects the very shader that is best suitable for rendering that material. The selection is automatic in most cases, but can also be manually overridden by the material.
Even the case that there is a non-optimal assignment may sometimes occur, e.g. when on the underlying hardware no shader can be implemented that renders the desired material perfectly. In this case, a sub-optimal (but still the best) shader is selected. This mechanism provides a fall-back solution for arbitrarily old hardware, meeting another important design goal of the MatSys.
Shaders therefore provide the key to be able to always support new hardware: If new 3D hardware features become available, we can quickly write a new shader for it, put it into the appropriate renderer, and then materials can use it, either from auto-selection or by explicit statement. This ability is a great feature that makes it easy to scale the MatSys for future hardware, limited (e.g. embedded) hardware, old hardware, etc.
Future SDKs will come with the ability to plug-in custom shaders, and the Wiki documentation about shaders will updated until then.
Summary¶
Technically and internally, the MatSys is organized as follows:
The real shaders actually have different names than in this
sketch, but shaders with the same name (e.g.
Shader B
) all (try to)
render a given material in the same way – as much as that is possible on
the underlying rendering technology.
The shaders of each renderer may ship as built-in shaders or can be provided as custom plug-in shaders by MOD authors.
The Materialviewer¶
The Cafu SDK comes with a Materialviewer program, that can load and render a material in the same way the engine would.
The program is therefore a very useful utility to test your materials and see how they will look in the engine.
The command-line¶
The Materialviewer is a command-line driven program. If you run it without any parameters, it prints a short help message:
C:\Cafu-9.06> MaterialViewer.exe
Cafu Material Viewer (Jul 04 2009)
Warning: Games/DeathMatch/Textures/TechDemo.zip: No such file or directory
Warning: Games/DeathMatch/Textures/SkyDomes.zip: No such file or directory
Please use the -m option in order to specify the desired material!
OPTIONS:
-m=MyMaterial specifies the name of the desired material, which must be
defined in one of the material script files (see below).
-bd=base/dir specifies the base directory from which I look both for material
scripts and the materials associated textures.
The default (if you don't use -bd) is Games/DeathMatch
-ms=MyMatScript.cmat specifies the material script that contains a definition
of "MyMaterial" (see above). You may use -ms several times, making me look
into each specified script for a definition of the material.
If you do not use -ms at all, I'll look into ALL material scripts that I can
find in Games/DeathMatch/Materials, so you probably don't need it as well.
-r=RendererXY overrides the automatic selection of the "best" renderer,
and loads the renderer with base name RendererXY instead.
Only provide the base name (e.g. RendererOpenGL12), no path and no suffix.
In most cases, just pass the name of the desired material as shown in The Material Browser in order to run the Materialviewer. Example:
C:\Cafu-9.06> MaterialViewer.exe -m=TechDemo/walls/wall-13f
The Materialviewer Window¶
The Materialviewer window contains a cube whose faces are applied with the selected material. The cube is surrounded by 4 walls, that have also the material applied. The bottom and top of this “room” are colored black.
You can turn on up to 4 dynamic light sources, that move around the
scene and illuminate the cube from different angles. Light sources come
in 4 colors (white, red, green, blue) and can all be activated
separately using the keys 1-4
.
Keyboard and Mouse Controls¶
Use the following keys to control the Modelviewer:
Key | Action |
---|---|
ESC |
Quits the program, same as ALT+F4 . |
1 |
Toggles if white light is visible. |
2 |
Toggles if red light is visible. |
3 |
Toggles if green light is visible. |
4 |
Toggles if blue light is visible. |
The following keys can be held down to achieve an effect:
Key | Action |
---|---|
W or Arrow key up |
Moves the camera forward. |
S or Arrow key down |
Moves the camera backwards. |
A or Arrow key left |
Strafes the camera to the left. |
D or Arrow key right |
Strafes the camera to the right. |
Further on you can change camera direction along the x axis by holding down the left mouse button and moving the mouse left or right.
The Materials (cmat files) Manual¶
Cafu materials are defined in material script files, which in turn are
simple ASCII text files with file name suffix .cmat
. This page
describes how such “cmat scripts” can be written, their syntax and
semantics.
Overview¶
First of all, here is a simple example for a material definition script.
It was taken from the Cafu-9.06/Games/DeathMatch/Materials/Kai.cmat
file, which also contains several other, very similar material
definitions:
Textures/Kai/3r_metpan01 // Material definitions start with the material name.
{
diffusemap Textures/Kai/3r_metpan01_diff.png // This line says which texture is used as diffuse-map.
normalmap Textures/Kai/3r_metpan01_norm.png
specularmap Textures/Kai/3r_metpan01_spec.png
lightmap $lightmap
}
Before we dig into the details about keywords and structure of such material definitions, here are some general properties of cmat files:
- cmat files are simple ASCII text files, containing material
definition scripts. Their file name ends with
.cmat
. - All statements in such files are case-sensitive. That means that
text
andText
are not the same. This is also true for filenames, like theTextures/Kai/3r_metpan01_diff.png
filename above, because some operating systems like Linux have a case-sensitive file-system. - C++ style comments are allowed in material scripts:
// This is a comment.
- The cmat files for MOD “MyMOD” are all stored in the
Cafu-9.06/Games/MyMOD/Materials/
directory and its subdirectories. This is necessary because the Cafu engine automatically scans this directory for material scripts whenever MOD “MyMOD” is run. - Tokens in cmat files are separated by white-space and these
individual characters:
( { [ ] } ) ,
- Quoted tokens are recognized. That is, everything between two
"..."
is considered as one statement, even if white-space or one of the above characters is inside it. That means, if for example you really want to have a material name likemy(new and cool)material
, then you have to enclose it in quotation marks like this:"my(new and cool)material"
in order to account for both the white-space and the brackets. Using quotation marks is not recommended, though! They’re mostly useful if somebody created textures with weird file names like for example"{_SomeFile.bmp"
. WriteMyNewAndCoolMaterial
orMy/New/And/Cool/Material
or something similar for your material names instead.
Material definitions always start with the material name. In the
example above, that’s Textures/Kai/3r_metpan01
. You can name
materials almost anything you like. If you want to use white-space,
commas or brackets in their name, you’ll have to put the name into
quotation marks as mentioned above. However, it is important that the
name is unique. If the same material name appears again in any other
cmat file of the same MOD, the engine will use only the first occurance,
so the chances are 50:50 that your material wins over the other. Most
materials that come with Cafu have a filename that roughly resembles the
name of its texture image files. That is often a helpful hint for
conveniently working with the material, but by no means a requirement.
The body of the material definition is enclosed in a pair of
{ … }
. In many cases, it will only contain a few texture map
specification statements like in the example above.
Texture Map Specifications¶
The simplest form of a material definition is to only specify the texture map images that compose the material. The previous example, repeated here, was an example for such a simple definition:
Textures/Kai/3r_metpan01 // Material definitions start with the material name.
{
diffusemap Textures/Kai/3r_metpan01_diff.png // This line says which texture is used as diffuse-map.
normalmap Textures/Kai/3r_metpan01_norm.png
specularmap Textures/Kai/3r_metpan01_spec.png
lightmap $lightmap
}
A texture map specification starts with a keyword (e.g. diffusemap
)
and is followed by a “map composition”.
Map compositions are normally just the path plus file name of a texture
image relative to the MOD directory, like for example
Textures/Kai/3r_metpan01_diff.png
. However, map compositions can
also be more complex constructs as explained in the next section
Map Compositions.
The initial keyword (diffusemap
etc.) defines how the texture image
is used in dynamic lighting computations during rendering. This is very
similar to Doom3 materials, and both Cafu and Doom3 implement in this
regard a form of the Phong lighting model.
Here comes a list of all available keywords for texture map specifications, along with a short description of their default meaning. (The default is dynamic Phong lighting, which however can be overridden, as explained at Shader Specifications.)
diffusemap
- The texture map image that defines the diffuse color (or diffuse reflectivity) of the material. The alpha channel of the diffuse-map specifies the translucency of the material.
normalmap
- The texture map image that specifies the color-encoded normal-map of the materials surface. The normal vectors must be specified in tangent space, range compressed (-1 to 1 maps to 0 to 1), and the y-axis points top-down. Note that heightmaps can be converted into normal-maps as described in section Map Compositions below.
specularmap
- The image for the materials specular highlights.
lumamap
- This texture map image defines the luminance for this material. Note that the light emittance that is defined here is local only (as is a general property of the Phong lighting model). It is not cast onto other surfaces.
lightmap
- This materials lightmap image. This image is normally computed and
provided by the Cafu engine or the program (e.g. the material viewer
or CaWE) with which you use the material. Although you can provide
texture map file names as with the above keywords, that rarely ever
makes sense. Normally, simply specify the special lightmap
$lightmap
in combination with thelightmap
keyword in order to use whatever lightmap the Cafu engine provides for this material. This is demonstrated in the preceding example. (!) If you don’t use this keyword at all, or specify something different than$lightmap
, the compile tools will not cover surfaces that use this material with a lightmap, and these surfaces will neither receive nor reflect Radiosity light. Note that for many effect materials, this is desired and very useful behaviour, as for example with decals, skies, water surfaces etc. shlmap
- The image that contains color-encoded coefficients for Spherical
Harmonic Lighting for this material. As for lightmaps, you may
specify arbitrary texture map file names with this keyword, but
normally just use
$shlmap
in order to let the engine supply the proper SHL map. cubeMap
A six-sided cube-map image that is used e.g. for environmental mapping. Normally, cube-map specifications are per default ignored, because they are not regularly used with Phong lighting. Instead, they are specially activated as described in section Shader Specifications. As a single cube-map is actually composed of six individual images, a special convention for its file name is employed: A
'#'
character in the file name is automatically replaced with the six possible cube-map suffixes _px, _nx, _py, _ny, _pz and _nz. For example, consider this material definition from theCafu-9.06/Games/DeathMatch/Materials/SkyDomes.cmat
file:Textures/SkyDomes/PK_BrightDay2 { AmbientShader A_SkyDome LightShader none // == noDynLight // The '#' in the next line is auto-replaced with the relevant suffixes (_px, _ny, ...). cubeMap Textures/SkyDomes/PK_BrightDay2#.png, wrapS clampToEdge, wrapT clampToEdge // ... }
This example has keywords and elements that will be explained further below, but for now observe that the file name that is assigned to the cube-map is
Textures/SkyDomes/PK_BrightDay2#.png
. When the Material System loads the six individual images from disk, it will therefore load them from the filesTextures/SkyDomes/PK_BrightDay2_px.png
,Textures/SkyDomes/PK_BrightDay2_nx.png
,Textures/SkyDomes/PK_BrightDay2_py.png
, and so on.cubeMap2
- This is like the above
cubeMap
keyword. It allows you to specify a second cube-map for special-purpose shaders that require two cube-maps. This keyword too is normally ignored unless a shader is specified that makes use of it. See Shader Specifications for more details.
You can specify arbitrary combinations of these keywords in one
material, as only the diffusemap
keyword is mandatory. However, if
you use the same keyword more than once, only the last occurrence is
considered. The order of the keywords occurrences is not relevant.
Map Compositions¶
Texture map image specifications with the above keywords can not only be simple file names, but also be more powerful Map Compositions. A map composition is a description of how a single texture map image is composited from several source images on disk. Here is an example for a simple material whose normal-map is defined by a complex map composition:
Textures/Kai/barrel_rst
{
diffusemap Textures/Kai/barrel_rst_diff.png
normalmap combineNMs(MyNm1.png, hm2nm(add(MyHm2.jpg, MyHm3.tga)))
lightmap $lightmap
}
(This example is overly complex for demonstration purposes, and not really meaningful. Real-life examples are normally much simpler.)
The expressions that are valid to define a map composition are defined as follows. Please note that the arbitrary nesting of expressions is expressly permitted, yielding great freedom for artists.
filename
- This is the most simple expression: a path plus a filename, as e.g.
Textures/Kai/barrel_rst_diff.png
in the above example for thediffusemap
. The path is relative to the directory of the MOD for which this material script was written. Supported file extensions include png, tga, jpg and bmp. add(e1, e2)
- This expression adds the colors of
e1
ande2
, wheree1
ande2
can be arbitrary sub-expressions. The resulting RGBA values are clamped to 1.0. mul(e1, e2)
- This expression multiplies/modulates/filters the colors of
e1
ande2
. combineNMs(e1, e2)
- Treats the colors of
e1
ande2
as color-compressed normal vectors, and combines or “adds” them in a mathematically correct fashion. (This it not the same as theadd(…)
operation.) hm2nm(e1, scale)
- Assumes that
e1
is a gray-scale heightmap and converts it into a normal-map. The relative height of the heightmap is scaled by factorscale
in order to weaken or pronounce the resulting effect. Values between 1.0 and 10.0 are normal use, but numbers greater than 10.0, less than 1.0, or even negative numbers are allowed, too. flipNMyAxis(e1)
- Considers the colors of
e1
as color compressed normal-vectors, and flips their y-component. This is useful for normal-maps that have their y-component pointing into the wrong direction. Such normal-maps occurred in the early days of dynamic lighting or were created for other programs than Cafu. This function is for fixing such cases, and should rarely be needed. renormalize(e1)
- Considers the colors of
e1
as color compressed normal-vectors, and renormalizes them (scales them to unit length). This is mostly useful for testing and debugging. blue2alpha(e1)
- This function is for use with old diffuse-maps. It replaces the alpha
channel of
e1
with value 0.0 (transparent) if the RGB color at this pixel is pure blue (0.0, 0.0, 1.0), and 1.0 (opaque) otherwise. Moreover, pure blue pixels are replaced with the average pixel color of the non-blue pixels in order to account for texture filtering. (automatic scaling)
- Whenever you employ one of the above expressions to combine the
results of two expressions
e1
ande2
that have different lateral dimensions,e2
is automatically scaled to match the size ofe1
.
You can apply map composition expressions to all above mentioned
texture map specification keywords, i.e. they work with diffusemap
,
normalmap
, specularmap
, cubemap
, etc.
Technically, a map composition is completed before the Cafu engine or the graphics board see them. In other words, the engine or the 3D hardware never see the individual images, only the composite result. Everything that is done by these composition steps could also be pre-worked by the artist in an image processing software. There would benodifference for the engine, the hardware, or in the resource (memory) consumption. Note that this feature has nothing to do with dynamic lighting or how a texture map image is combined with images of other texture map specification keywords!
Finally, you can specify several comma-separated options for the map composition:
minFilter
This controls MipMap usage and the filter that is used for texture minification. While the default setting usually looks best and also yields the best performance on modern graphics hardware, sometimes it is desireable to turn filtering off and accept some aliasing, as for example for font textures. The
minFilter
keyword must be followed by one of the filter methodsnearest
orpoint
linear
orbilinear
nearest_mipmap_nearest
nearest_mipmap_linear
linear_mipmap_nearest
linear_mipmap_linear
ortrilinear
(This is the default.)
magFilter
This controls the filter that is used for texture magnification and must be followed by one of
nearest
- or ``point`` (There is almost never a reason to use this, except for very rare and special purposes, like some kinds of debugging.)
linear
- or ``bilinear`` (This is the default and gives best results.)
wrapS
This controls horizontal texture coordinate wrapping and must be followed by one of
repeat
- for repeating the texture in horizontal direction. This is the default.
clamp
- for clamping the texture in horizontal direction, taking the
border color into account. As the Cafu MatSys never uses or sets
the border color, using
clamp
is rarely ever useful. clampToEdge
- for clamping the texture in horizontal direction to its edge color. Often useful with cube-maps or terrain base images.
wrapT
This controls vertical texture coordinate wrapping and must be followed by one of
repeat
- for repeating the texture in vertical direction. This is the default.
clamp
- for clamping the texture in vertical direction, taking the border
color into account. As the Cafu MatSys never uses or sets the
border color, using
clamp
is rarely ever useful. clampToEdge
- for clamping the texture in vertical direction to its edge color. Often useful with cube-maps or terrain base images.
noScaleDown
- specifies that the texture image is never scaled down, not even if
the user selects a medium or low texture detail setting for tuning
the graphics performance. Useful for fonts, HUDs, lightmaps
(implicitly), some model textures (see example below), and everything
else that must not get mixed up or blurred by image filtering. Also
used e.g. for the Cafu splash screen logo, which would get blurred
otherwise (look into
Games/DeathMatch/Materials/Splash.cmat
if you want to toy around with it a little 🙂 ). noCompression
- exempts this texture image from being stored in a compressed format
in video memory, even if the user generally enabled texture
compression for tuning the graphics performance.
In the Cafu engine, texture compression is by default enabled for all
texture images except normal-maps. Although Cafu automatically
selects and employs the latest and highest quality compression method
that the graphics driver offers (this even works when the Cafu
executable is older than the driver!), sometimes the compression
process comes with some loss of image detail or introduces small
artifacts.
noCompression
can then be used to ensure no compression for a particular texture. useCompression
- is more or less the opposite of
noCompression
: it turns compression back on. Normally there is no reason to ever use this keyword. It exits for symmetry tonoCompression
and becausenoCompression
is the default for normal-maps: if you want to have compression enabled for a particular normal-map, specifyinguseCompression
will turn it on. However, please note that compression artifacts in normal-maps tend to disturb the lighting computations so much that the generated output images drop to questionable quality. Also note thatuseCompression
is “weak”: If the user generally disables all compression, it will have no effect.
The meaning of the minFilter
, magFilter
, wrapS
and wrapT
options is analogous to their respective meanings in the OpenGL and
DirectX APIs. The OpenGL Programming Guide (the “Red Book”) about OpenGL
version 1.2 and higher has a good explanation about these options.
Although the text is specific to OpenGL, the same concepts apply to the
above mentioned options. The “Red Book” for version 1.1 does not address
the clampToEdge
option, but its text is available online at
http://www.rush3d.com/reference/opengl-redbook-1.1/chapter09.html.
The options noScaleDown
and minFilter bilinear
are often
combined, because both scaling down textures for better graphics
performance as well as using trilinear
filtering for rendering have
a tendency to mix the colors of neighboring pixels. In some cases such
as font textures, even the bilinear
filtering is too much mix-up,
requiring us to combine noScaleDown
with minFilter nearest
.
Options Example 1¶
Here is an example from Games/DeathMatch/Materials/Fonts.cmat
that
demonstrates how the options are used:
Fonts/Arial
{
diffusemap ../../Fonts/Arial.png, minFilter nearest, magFilter nearest, noScaleDown
// ...
}
Options Example 2¶
Another example for the noScaleDown
and minFilter
keywords.

A straightforward material definition would look like this:
Models/Players/Trinity/trinityskin3
{
diffusemap Models/Players/Trinity_Skin_diff.png
red ambientLightRed
green ambientLightGreen
blue ambientLightBlue
}
The image to the left shows the result of the this material definition being applied to a model mesh. Notice the small glitch in the image, which is a result of mipmaps being applied to the above shown texture: Mip-mapping mixes black pixels of the hair with adjacent, bright pixels of the skin, yielding the intermediate colors that are marked in the result image to the left. Such glitches are even more disturbing and better visible with animated models, e.g. when the head of the model slightly turns.
With the
noScaleDown
and minFilter bilinear
keywords
applied in the material script, the glitch disappears as shown here:
Models/Players/Trinity/trinityskin3
{
diffusemap Models/Players/Trinity_Skin_diff.png, minFilter bilinear, noScaleDown
red ambientLightRed
green ambientLightGreen
blue ambientLightBlue
}
Shader Specifications¶
The examples of material definitions that we have seen so far were only composed of texture map specifications. In the MatSys Introduction we have learned that internally, “shaders” take materials to finally implement how they are rendered and how they look. In cases like our example materials above, the MatSys selects shaders from a built-in library automatically, picking the one that best fits the material.
But what if you want to change the way how your materials are rendered, either just in the details or radically from ground up? What if you don’t want regular Phong lighting? Or you want an entirely different method to render diffuse-maps or a different way to combine them with normal-maps? What if the built-in shaders don’t cover a way of rendering that you prefer? It also happens that the built-in shaders do not take cube-maps into account at all, so what if you want to have a material with cube-map environment reflections?
The answer to these questions is two-fold: You have to override the automatic shader selection by assigning a shader manually. But you also have to “know” that shader: You have to know its name, or you cannot assign it to your material. You have to know wether it needs a diffuse-map or a cube-map or both, or any other combination of texture map images, so that you can specify them in your material definition. Sometimes you have to know even more details about it.
The good news is that the MatSys renderers have more shaders built-in than just those that are considered during the automatical selection. They are documented below, inclusive sample material definitions, and you can use them to override the auto-selection. Alternatively, if you know or are a programmer, you can also make your own shaders. By making own shaders you gain the greatest flexibility that you can get, because only shaders eventually define how materials look, and shaders can do everything that the underlying hardware can do!
There is another issue that you should know about shaders: Each material gets not only one shader assigned, but two. This is because the Cafu Material System renders materials in two steps: First, the ambient part of a material is rendered, that is, everything that is rendered even if no light source is present. The ambient shader of a material is responsible for how this part is rendered. Then, the parts of the material looks that are contributed by each light source are rendered separately, as for example diffuse reflections, specular highlights and other effetcs. The per-light-source contributions are controlled by the light shader of a material.
You set the ambient and light shader of a material (and thereby override the automatic selection) with the following keywords in the material definitions body:
AmbientShader MyAmbientShader
- assigns the shader with name
MyAmbientShader
as the ambient shader to this material. LightShader MyLightShader
- assigns the shader with name
MyLightShader
as the per-light-source shader to this material.
Here is an example for how these statements could be used in a material definition:
Textures/Kai/barrel_rst
{
AmbientShader myCarMetallicBlue_ambient
LightShader myCarMetallicBlue_light
diffusemap Textures/Kai/barrel_rst_diff.png
normalmap flipNMyAxis(Textures/Kai/barrel_rst_norm.png)
cubeMap Textures/SkyDomes/ReflectiveCubeMap#.jpg
}
Built-in special-purpose Shaders¶
Currently, all MatSys renderers come with several special-purpose shaders built-in (special-purpose means that they are never taken into account for automatic assignment). In most cases, they are actually pairs of shaders, one shader for the ambient and one shader for the per-light contribution of the same effect, but you will find that the exception to this rule is more often true than not. More built-in shaders are currently in preparation, for example for special effects like cube-map environment reflections, realistic water surfaces, etc. Note that any programmer can also write his own shaders, allowing him to implement any rendering effect that he wants! This makes the MatSys highly flexible, extensible and future-proof, and was one of its primary design goals.
The following special-purpose shaders are currently built into all renderers of the MatSys. Please note these shaders and their related examples are pretty advanced, and you might want to skip them until later. It may be convenient to first finish reading the rest of this documentation, which will help to fully understand the special-purpose shader examples.
The SkyDome Shader¶
In order to create surfaces that are invisible like fully transparent glass and instead only show the far sky dome beyond them, the ambient shader ``A_SkyDome`` exists. It basically only requires a cube-map for the sky to be specified. In fact, it ignores the specification of any other (i.e. diffuse-, normal-, etc.) maps. However, in most cases you’ll want to specify additional keywords that further describe the properties of the sky surfaces. Here is an example:
Textures/SkyDomes/PK_BrightDay2
{
// Activate the A_SkyDome shader as the ambient shader
AmbientShader A_SkyDome
// Have no dynamic light affect surfaces with this material.
LightShader none
noDynLight
// The '#' in the next line is auto-replaced with the relevant suffixes (_px, _ny, ...).
cubeMap Textures/SkyDomes/PK_BrightDay2#.png, wrapS clampToEdge, wrapT clampToEdge
// Don't write into the z-Buffer, so that entities (like missiles) outside of the map can still be drawn.
ambientMask d
// This material does not cast dynamic shadows.
noShadows
// Don't create or keep lightmaps for this material, don't participate in Radiosity computations.
meta_noLightMap
// This keyword states that this material casts sunlight.
meta_sunlight
// The irradiance of the sunlight in Watt/m^2 that comes (or shines) through this material.
// Values like (100 90 80) might work, too.
(220 180 100)
// The direction of the incoming sunlight rays. The z-component should be negative.
// (These values match the actual position of the sun in the cube-maps.)
(-17 -699 -715)
}
The ``AmbientShader A_SkyDome`` line activates the ambient sky dome shader. Note that the far away sky dome is not affected by light of any dynamic light source, and therefore we assign the ``none`` shader as the per-lightsource shader in order to make sure that no dynamic light is applied to sky surfaces. The ``noDynLight`` keyword does essentially the same as ``LightShader none`` and will soon be obsoleted. Until then, please use it together with each occurrence of ``LightShader none``.
The ``cubeMap …`` statement specifies the cube-map that is to be used for this sky. If you also specified other texture maps like diffuse-maps or specular-maps, they would simply be ignored, as the ``A_SkyDome`` shader has no use for them.
The remaining keywords further specify important properties of this material. Please refer to section Keyword Reference for a detailed description. Short explanations of their meanings are given in the comments in the above example.
The Terrain Shader¶
The terrain shader exists in order to render the Cafu outdoor terrains, which work a bit different than regular, Phong-lit surfaces. You activate the ambient terrain shader by writing
AmbientShader A_Terrain
in the materials body. Normally, you would now to expect to also assign a terrain-specific shader for the per-lightsource contribution to the terrain, as in
LightShader L_Terrain
However, I have not yet written the ``L_Terrain`` shader, and so we have to turn off dynamic lighting for terrains:
LightShader none
noDynLight
(?) Why do terrains not account for light by dynamic light sources? Well, there are several reasons:
- Terrain is typically employed by mappers in outdoor areas that are in bright sunlight. The effect of dynamic light sources would barely be visible, if at all (but cost a lot of performance instead).
- Dynamic light sources are normally very “small” when being compared to the extends of terrains, and mappers tend to place them inside buildings rather than in the open area. This further limits the per-lightsource contribution on terrain surfaces.
- I simply have not yet had the time to write the ``L_Terrain`` shader.
(!) But if for example somebody wanted to model an indoor cave with the Cafu terrain technique, having a shader that accounts for the light of dynamic light sources even on terrains would make a lot of sense. Good news is that, as indicated above, it is easy to write such a shader – I’ll probably do so as soon as I need one.
Next, the ``A_Terrain`` (and the future ``L_Terrain``) shader requires a diffuse-map to be specified. This diffuse-map will be scaled to match the physical size of the terrain, that is, it will cover the terrain completely. In order to get the edges of the terrain properly textured, it makes sense to also specify ``clampToEdge`` border wrapping for the diffuse texture:
diffusemap Textures/Terrains/BPRockB_tx1.png, wrapS clampToEdge, wrapT clampToEdge
lightmap $lightmap
As the Cafu map compile tools will also generate a lightmap for the terrain in order to e.g. take sunlight or other radiosity light sources into account, we specify the ``lightmap`` keyword with the engine-supplied lightmap. Note that while the lighting of dynamic light-sources is not taken into account, the light of radiosity light sources is!
Next, the ``A_Terrain`` shader employs the texture-map that is specified with the ``lumamap`` keyword as a detail-map for the terrain. This is a good example for how the specification of a custom shader (here ``A_Terrain``) can entirely alter the meaning of a material keyword. We will see below how the coarseness (the repetition-count) of the detail-map is set.
lumamap Textures/Terrains/CommonDetail2.png // "A_Terrain" takes the Luma-map as Detail-map (optional).
The detail-map is optional, and may be omitted. However, terrains look a lot better with them, and so their use is recommended.
Finally, you need this block of statements in the body of your material definition:
shaderParamExpr fParam4 // The first eight shader parameters are taken from fParam4 to fParam11
shaderParamExpr fParam5 // and specify the coefficients of two planes for automatic tex-coord generation.
shaderParamExpr fParam6
shaderParamExpr fParam7
shaderParamExpr fParam8
shaderParamExpr fParam9
shaderParamExpr fParam10
shaderParamExpr fParam11
shaderParamExpr 21.3 // Scale / repetitions of the Detail-map.
The only thing that you may change here is the number of repetitions of the detail-map, 21.3 in the above example. The lines above that are required in order to get the terrain properly rendered and cannot reasonbly be altered.
For more information on what all the ``shaderParamExpr fParam*`` lines do, please refer to section (FIXME!) (TODO).
Here is a complete example for a terrain shader:
Terrains/BPRockB_tx1
{
AmbientShader A_Terrain
LightShader none
noDynLight
diffusemap Textures/Terrains/BPRockB_tx1.png, wrapS clampToEdge, wrapT clampToEdge
lightmap $lightmap
lumamap Textures/Terrains/CommonDetail2.png
shaderParamExpr fParam4 // The first eight shader parameters are taken from fParam4 to fParam11
shaderParamExpr fParam5 // and specify the coefficients of two planes for automatic tex-coord generation.
shaderParamExpr fParam6
shaderParamExpr fParam7
shaderParamExpr fParam8
shaderParamExpr fParam9
shaderParamExpr fParam10
shaderParamExpr fParam11
shaderParamExpr 21.3 // Scale / Repetitions of the Detail-map.
twoSided // "twoSided" is required for the SOAR terrain algorithm.
}
The WaterCubeReflect Shader¶
In order to turn a polygon into a translucent water surface with moving waves and reflected environment with Fresnel effect, employ the ``A_WaterCubeReflect`` shader: (FIXME!) (This section is not complete!)
The “none” Shaders¶
You can use the special ``none`` shader both as an ambient or a per-lightsource shader in order to have no shader for ambient or per-lightsource contributions at all.
As you have seen in the examples above, this makes sense in several situations. Especially materials that are not affected by local, dynamic light sources often have the ``LightShader none`` statement, as for example for sky dome. Note that currently, you still have to combine any ``LightShader none`` statement with the ``noDynLight`` statement in order to take proper effect. The ``noDynLight`` will however become obsolete in future releases of the Cafu Material System.
Using ``AmbientShader none`` is much less frequently useful, and almost only ever employed for “invisible” materials. Note that ``AmbientShader none`` also implies ``LightShader none``. Also, in order to take proper effect, the ``noDraw`` keyword is required with each occurrence of ``AmbientShader none``, but that requirement will be removed and ``noDraw`` be obsoleted in future versions of the MatSys.
Expressions and Tables¶
Some material keywords take not only plain numbers as their parameters, but entire mathematical expressions that are evaluated whenever the material is employed for rendering. Expressions in turn may refer to look-up tables, which are a very simple but flexible means to approximate arbitrary mathemathical functions.
This section explains the details of expressions and tables.
Expressions¶
Some of the above keywords cannot only take numbers as their arguments, but entire mathematical expressions. An expression is a combination of numbers, mathematical operations, symbols, and table look-ups. Here is an example for such an expression:
(1 + sinTable[ time*0.25 + 3 ]) / 2
Unfortunately, there is also bad news: The current parser of the Cafu
MatSys is not yet powerful enough to parse expressions that use operator
infix notation like the one above. Instead of +
, -
, *
, … we
therefore have to use explicit prefix notation, which is much easier to
parse. The prefix notation is explained below. Here is the above example
in prefix notation that we have to use until I can improve the parser to
support infix notation:
div(add(1, sinTable[ add(mul(time, 0.25), 3) ]), 2)
Expressions are defined recursively as follows:
$num
- A number.
$var
- A variable. Please see below for a list of all valid variables.
$table[ $expr ]
- A table look-up. The value of the table at position
$expr
is returned. The details of the look-up depend on the tables definition. The default tablessinTable
andcosTable
are always predefined. Custom tables can be defined as described in subsection Tables. Note that table look-ups are normalized. That is, all table elements are accessed by indices between 0.0 and 1.0, that is, the fractional part of$expr
. add($expr1, $expr2)
- Adds the results of
$expr1
and$expr2
. sub($expr1, $expr2)
- Subtracts the results of
$expr1
and$expr2
. mul($expr1, $expr2)
- Multiplies the results of
$expr1
and$expr2
. div($expr1, $expr2)
- Divides the results of
$expr1
and$expr2
if$expr2
is not 0. Otherwise, this evaluates to 0.
The following variables are defined:
time
- The current system time in seconds, starting from zero.
ambientLightRed
,ambientLightGreen
,ambientLightBlue
- The Cafu engine provides the color of the ambient light that is
contributed by radiosity light sources in these variables.
Therefore, almost all material definitions that are employed with
entities (e.g. player models, weapon and item models, etc.)
normally use these variables so that the entity is colored according
to the ambient radiosity light. Please see the
.cmat
files inGames/DeathMatch/Materials/Models/
for many examples.
Tables and table look-ups are described in subsection Tables.
Tables¶
A special expression is a table look-up of the form
$myTable[$indexExpr]
, where $myTable
is the name of a table that
must have been defined before use, and $indexExpr
is another
expression that determines where in $myTable
the look-up occurs. The
scope of $myTable
begins at its definition and ends at the end of
the material script.
Here is a simple but complete example with a table of four values:
// This line defines the table "myTestTable":
table myTestTable { { 0.2, 1.4, 0.6, 1 } }
TestMaterialForTableLookup
{
diffusemap someDiffuseMap.png
// ...
rgb div(myTestTable[mul(time, 0.5)], 1.2) // equiv. to: rgb myTestTable[time*0.5]/1.2
}
As you can see, table definitions start with the keyword table
,
followed by the name of the table. Then come two {
brackets, the
table data values separated by commas (arbitrarily many), and then the
closing two }
brackets.
Note that table data values are always mapped into the range 0 to 1.
Therefore, the graphical representation of myTestTable
looks like
this:
You may wonder what you get for myTestTable[x]
if x is smaller than
0 or greater than 0.75, or what happens if x is “between” two table
values. Per default, table values are infinitely repeated outside of the
range 0 to 1, and linearly interpolated between two adjacent values.
Therefore, myTestTable
from the above example in fact represents the
following function, graphically shown in light blue color:
Observe how the values repeat with each integral number. That
is, the table in range 0 to 1 is repeated between 1 to 2, between 2 to
3, 3 to 4, and so on. It is also repeated into the negative range, that
is from -1 to 0, from -2 to -1, -3 to -2, and so on.
myTestTable[0.375]
(in the mid between 0.25
and 0.5) yields 1.0 as the result.For example, if you access myTestTable
via the MatSys variable
time
, as in myTestTable[time]
, then it always takes exactly one
second to traverse the entire table. If you want to change the speed
with which the table is traversed, then you’ll have to multiply the
index variable time
with an appropriate scale factor. For example,
myTestTable[div(time, 3)]
will take three seconds to walk the entire
table once.
snap and clamp¶
For special-purpose tables, you can insert the keywords snap
and/or
clamp
between the two opening {
brackets of the table
definition.
``snap`` turns the linear interpolation off, and instead repeats the
previous value until the next table value. Thus, if we changed the
definition of our myTestTable
above to
table myTestTable { snap { 0.2, 1.4, 0.6, 1 } }
then our graphical representation of the table becomes:
Snapping is useful whenever you want to have a table to encode functions that have “hard” rather than “smooth” transitions. For example, in order to have LEDs flicker the SOS morse code, you’d use this table:
table sosTable { snap { 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0 } }
``clamp`` turns off the repetition of the table values outside of
the range 0 to 1. That is, adding clamp
to our definition of
myTestTable
yields:
table myTestTable { clamp { 0.2, 1.4, 0.6, 1 } }
clamp
, the first table value is returned for
myTestTable[x]
where x is less than 0, and the last table value is
returned whenever x is greater than 1 (in fact, greater than
1-1/TableSize).Finally, you can also combine snap
and clamp
:
table myTestTable { snap clamp { 0.2, 1.4, 0.6, 1 } }
Predefined Tables¶
Normally, tables must be defined before their first use, but there are also tables that are inherently defined by the MatSys and can always be used without prior definition:
sinTable
- yields the sinus of its argument. Note that the entire 360° (2pi) arc is compressed into the range 0 to 1, not 0 to 2pi.
cosTable
- yields the cosinus of its argument. Note that the entire 360° (2pi) arc is compressed into the range 0 to 1, not 0 to 2pi.
sinTable01
- like
sinTable
, but the values are not returned in range -1 to 1, but “compressed” to 0 to 1. That is,sinTable01[x]
is equivalent todiv(add(sinTable[x], 1), 2)
. cosTable01
- like
cosTable
, but the values are not returned in range -1 to 1, but “compressed” to 0 to 1. That is,cosTable01[x]
is equivalent todiv(add(cosTable[x], 1), 2)
.
Keyword Reference¶
This section lists all keywords that are allowed in the body of a materials definition.
Some of the keywords influence the automatic selection of the shader for the material, others just give more control over the shader that is eventually used for the material, for making better use of the features of that shader, increasing its usefulness.
Note that the built-in shaders of all MatSys renderers were written to comply to the documentation of the keywords below, or rather, the documentation was written to reflect the implementation of the built-in shaders. If you employ a custom shader (e.g. a self-written one) instead, there is no guarantee that this shader interprets and implements the keywords in an identical manner, because the shader is flexible and free to do anything that its author made it to. This is where you need a documentation that is specific to that shader, see Built-in_special-purpose_Shaders for the built-in ones.
In general, most keywords should occur only once per material definition. If such a keyword is stated several times, only its last occurrence is taken into account, overriding its previous statements. The order in which such keywords are specified in the body of the material definition is irrelevant, you may state the keywords in any order.
Shader Specifications¶
AmbientShader $name
, LightShader $name
These keywords are used to override the automatic shader selection. They are explained in detail in section Shader Specifications.
The precise meaning of all other keywords is “vague”, that is, they depends on the implementation by the selected shader (!)
Texture Map Specifications¶
diffusemap $mc
, normalmap $mc
, specularmap $mc
,
lumamap $mc
, lightmap $mc
, shlmap $mc
, cubeMap $mc
,
cubeMap2 $mc
, shaderParamMapC $mc
With these keywords you specify texture map compositions ``$mc`` for use with this material. The keywords and texture map compositions are explained in detail in section Texture Map Specifications.
The ``shaderParamMapC`` keyword is special, as it can occur arbitrarily often! You can use it to pass an arbitrary number of texture-maps to the shader. Materials that employ a custom shader that for example combines several diffuse-maps and several normal-maps might use this keyword in order to list all the textures that the shader employs.
Custom Data¶
shaderParamExpr $expr
, shaderParamMapC $mc
Rendering Options (Universal)¶
The following material parameters are global rendering parameters. They affect the entire material, but only how it is rendered, that is, its “looks”. These parameters are never looked at or taken into account by the map compile tools.
noDraw
- If specified, this material does not render at all, it becomes
invisible. This is probably mostly useful for debugging. (For
mappers:
noDraw
does not cause CaBSP to remove any faces from the world. If you want faces to be actually removed, you should rather use themeta_XXX_TODO
keyword in order to make CaBSP remove them right from the start.) noShadows
- This material never casts shadows. Note that shadow-casting can also be controlled on a per-model and per-lightsource basis.
twoSided
- Normally, the back or “inside” faces of materials are not rendered. This renders both sides of the material. Useful for “indefinitely” thin objects like metal grates and fences, spider webs, … Note that two-sided faces are currently not properly lit by dynamic light when seen from the back side.
depthOffset $num
- This sets the polygonal depth offset. Z-buffer values of meshes that
are rendered with this material are slightly offset as defined by
$num, which should normally be a negative number. Materials that
employ
depthOffset -1.0
are for example used internally by CaWE, in order to render the highlighting of selected objects. polygonMode $pm
This sets the polygon mode of a mesh. CaWE employs this keyword for rendering the objects in the 3D wire-frame mode.
$pm
must be one offilled
wireframe
points
Rendering Options (Ambient only)¶
The following parameters do only affect the ambient contribution of a
material (as implemented by the Material Systems ambient default
shaders). The map compile tools never look at these parameters. Some of
these parameters take expressions as their arguments, which are denoted
by $expr
. Expressions can be simple numbers or more complex
constructs, they are discussed in greater detail in subsection
Expressions.
alphaTest $expr
- Activates the alpha test with the result of
$expr
as the reference value. The alpha test passes if and only if the alpha value of the ambient contribution (which normally comes from the diffuse-map) is greater than the reference value. Note that the reference value can be specified as an expression, that is, it can be varying over time. This can produce interesting effects (i.e. materials that appear to grow or shrink) if the diffuse-map comes with an appropriate alpha channel. Negative values turn the alpha test off. The test is off by default. blendFunc $src_factor $dst_factor
- This parameter determines the blend function for the ambient
contribution of the material.
$src_factor
and$dst_factor
must be one ofzero
,one
,dst_color
,src_color
,one_minus_dst_color
,one_minus_src_color
,dst_alpha
,src_alpha
,one_minus_dst_alpha
, orone_minus_src_alpha
. Note that not all combinations make sense. UsingblendFunc
will be documented in greater detail in future releases of this text. Per default, blending is turned off. red $expr
,green $expr
,blue $expr
,alpha $expr
,rgb $expr
,rgba $expr
- These parameters all define expressions for (channels of) the color with which the ambient contribution is modulated. I have defined the default ambient shaders such that for materials that have luma-maps, only the luma-map is modulated. Materials that have no luma-map get the entire ambient contribution modulated. This allows to create effects such as panels that have flickering LEDs, glowing lights etc. Note that you can specify different expressions for different color channels. That is, if you have a luma-map for a computer panel that has both red and green LEDs, you can for example have the red LEDs morse SOS, while the green LEDs change gradually by a sinus function. The default expression for all color channels is 1.0 (identity).
ambientMask $turnoff
- This specifies into which framebuffer channel should not be written
when rendering the ambient pass.
$turnoff
must be a combination of the charactersr
,g
,b
,a
andd
, wherer
refers to the red color channel,g
,b
anda
refer to the green, blue and alpha color channels respectively, andd
refers to the depth buffer value. For example,ambientMask d
is used with many particle (sprites) material definitions, in order to avoid that particles change the contents of the depth buffer, in order to meet the fact that particles are often rendered in an unsorted, additive manner.ambientMask d
is also used for sky-dome material defs, so that we are able to render e.g. far away missiles or other objects in the sky that would otherwise be rejected by the depth test against the (nearer) sky dome polygons. Note that employingambientMask d
, that is, not writing into the depth buffer during the ambient pass, also makes dynamic lighting of such affected meshes impossible. Therefore,ambientMask d
should always be combined withLightShader none
andnoDynLight
. (FIXME!): The MatSys should issue a warning if that is not the case. Another example for employing this keyword isambientMask gb
, which makes sure that nothing gets rendered into the green and blue color channels, leaving only red (and alpha and depth). This yields an effect similar to Doom3, when you see only red while the player has a foreboding vision. useMeshColors
- Additionally to the above color definitions, this will modulate the materials color with the colors that are specified with the vertices of the mesh that is to be rendered. This option does currently only work in a very limited set of shaders, and is mostly useful internally in CaWE, the Cafu World Editor, e.g. for rendering wire-frame stuff. You will rarely ever need this in a real-world material script.
Rendering Options (Light only)¶
noDynLight
- If specified, this material does not receive any light from dynamic light sources, only the ambient contribution is rendered. (Technically, the material does not even get a per-light-source shader assigned.) Useful e.g. for sky domes, additive effects like particles, translucent surfaces like water and glass etc.
lightMask $turnoff
- This is very similar to
ambientMask
, but it only affects the per-lightsource passes. This keyword is currently not used in any Cafu material.
Other Keywords¶
There are also keywords that define other aspects of the material that are not directly related to their rendering.
clip $c1, $c2, …
Defines for whom or for which purposes the material is considered solid in clipping (collision detection) computations. This is mostly interesting in game related settings (e.g. with player or monster clip brushes), but also programs like CaBSP and CaLight perform clip and ray trace tests that in turn are affected by this keyword.
$c1, $c2, …
must be a comma-separated list of at least one of the flags below. The default setting (i.e. if you do not use theclip
keyword at all), isclip all
. When you useclip
, the value is first cleared (reset tonothing
) and then additively rebuilt from the parameter list. Here is an explanation of the individual flags:nothing
means that a surface with this material clips against nothing, it is non-solid.players
means that the surface is solid to players.monsters
means that the surface is solid to monsters (AI entities).moveables
means that the surface is solid to moveable entities.ik
means that the surface is solid to IK.projectiles
means that the surface is solid to the projectiles of weapons (e.g. water surfaces, but not sky).sight
means that the surface blocks line-of-sight tests (used e.g. for AI).bspPortals
means that the surface clips portals, that is, it is solid to the flood-fill operation of CaBSP. (!) Note that each Cafu map must entirely be sealed by materials with thebspPortals
property, or else CaBSP will not be able to flood-fill it properly and report that the map has a leak. Developers, note that this means that maps can be made where objects can fall out of the map (e.g. through the floor). Considering the clip-world only, this can be desirable e.g. for rockets that are fired into the sky, even though Cafu has to treat them specially for drawing (render objects in non-PVS “outer” leaves). CaBSP issues a warning if it ever finds a material that hasbspPortals
, but not bothplayers
andmonsters
set, in order to make you aware that in such places, players or monsters could fall out of the map.radiance
means that the surface blocks the transfer of light energy in the Radiosity computations of CaLight (most walls do, but for example glass and decals usually don’t).all
means that the surface is solid to all of the above (but not thetrigger
flag below).trigger
means that the surface is part of a trigger volume. Entities that have trigger volumes can detect when something enters their volume and then take special actions. For example, a player that walks into a trigger volume can cause a script function to be run that in turn opens a door and spawns some monsters. Thetrigger
flag is normally not combined with any of the other flags, but for special cases it is still possible to write e.g.clip monsters, trigger
to define a material that is solid only to monsters and a trigger to everything else (e.g. players).
surfaceType $st
- Defines the type of the surface.
$st
must be one ofnone
,stone
,metal
,sand
,wood
,liquid
,glass
, orplastic
. The meaning of the surface types is solely defined by the game code, it will usually use them to play footstep sounds, ricochet effects, etc.
Meta Keywords¶
Finally, here are the meta-parameters that are taken into account by the Cafu map compile tools. These parameters are not directly related to the rendering of the material.
meta_radiantExitance $r $g $b $scale
- Radiant exitance RGB values plus intensity (scale). Used whenever a
material should also be a source of radiosity light, as computed by
CaLight. The radiant exitance is defined by
$r
,$g
and$b
, scaled by$scale
. meta_radiantExitance_byImage
- Radiant Exitance RGB values from image file. Used by CaLight, plus Radiant Exitance intensity (scale) for the RGB values from image file. Used by CaLight, but not yet implemented.
meta_sunlight ($r $g $b) ($x $y $z)
- This keyword states that the materials casts (radiosity) sunlight.
The first three numbers define the irradiance of the sunlight in
Watt/m^2 for the red, green and blue wavelengths. As the light
actually comes from a very far away lightsource (the sun, moon,
etc.), it is not cast by the materials itself, but rather through
them, like sunlight shining through a window. The second triple of
numbers specify the directional vector of the incoming light rays.
The
$z
number should always be negative, so that the light appears to come from above. In the fileGames/DeathMatch/Materials/SkyDomes.cmat
you can see exemplary use of this keyword. meta_alphaModulatesRadiosityLight
- Makes CaLight handle the
diffusemap
alpha channel and the $alpha and $rgba keywords properly. For fences, grates, glass, water, etc. Not yet implemented.
Getting Started with the Cafu Source Code¶
This text explains how you get and compile the Cafu source code.
Most steps that are explained below are only necessary once, when you get and compile the Cafu source code for the first time.
Getting the Source Code¶
This section explains how you obtain the Cafu source code by checking it out from its Git repository.
Git is a version control system that allows the Cafu developers to work on their copy of the source code independently of each other, and to distribute the latest version of the source code to other developers at any time. Moreover, many developers prefer to manage their project independently in their own version control system, but also wish to integrate the latest changes (e.g. bug-fixes and new features) from the official Cafu repository into theirs from time to time: Git makes the synchronization of the projects code with the original Cafu source code as convenient and automatic as possible. If you don’t know Git yet, have a look at the Git website and the Git documentation. The “Pro Git” book is very well written and available for free in several languages.
For Windows and many other systems, you can get Git from the Git downloads page. Popular Git clients with a graphical user interface are available at the Git downloads page as well.
With most Linux distributions, installing Git via the systems package manager is usually preferred. For example, under Ubuntu:
> sudo apt-get install git gitk
Then check out the source code at the command-line under Windows or Linux with this command:
> git clone --recursive https://bitbucket.org/cafu/cafu.git Cafu
Note the --recursive
option in the command above: it makes sure that
submodules are automatically checked out as well. As we keep the texture
images for the DeathMatch example game in a submodule, it is convenient
to have them checked out along with the main repository. Be prepared
though that this adds approximately 180 MiB to the download volume.
Our Git project page is https://bitbucket.org/cafu/cafu, where you can browse the repository online, create forks, post pull requests, and find additional help about Git.
Python and SCons¶
Cafu uses SCons as its software build system
on all supported platforms. SCons is a modern replacement for make
and Makefiles
. SCons requires the Python scripting
language to be installed, so that you have to
get and install both Python and SCons on your computer.
Windows¶
Under Windows,
- first get and install Python 2.7 (not one of the newer, but backwards-incompatible 3.x editions!) from http://www.python.org/download/,
- then get and install SCons 2.3 (or any later version) from http://www.scons.org/download.php.
If in doubt, pick the Windows installers for both Python 2.7 and SCons 2.3: they are easy to use, lightweight, and automatically setup the proper environment variables.
Important notes:
- Pick the 32-bit edition of Python even on 64-bit systems! (Unfortunately, SCons does not yet work with the 64-bit builds of Python.) That is, python-2.7.12.msi is the right file for all Windows systems.
- On Windows 7, 8 and 10, run the SCons installer via right-click, then select “Run as administrator”.
That is normally all, but you may wish to check if the Python installer
added Python’s Scripts
directory to the PATH
environment
variable of your system. For example, if Python was installed in
C:\Python27
, then PATH
should contain both C:\Python27
and
C:\Python27\Scripts
. Otherwise, you have to add the proper
directories manually: See http://support.microsoft.com/kb/310519 and
http://vlaurie.com/computers2/Articles/environment.htm for additional
information.
In order to verify that everything is working correctly, open a new
command prompt and enter scons -v
:
> scons -v
SCons by Steven Knight et al.:
script: v2.3.0, 2013/03/03 09:48:35, by garyo on reepicheep
engine: v2.3.0, 2013/03/03 09:48:35, by garyo on reepicheep
engine path: ['C:\\Python27\\Scripts\\..\\Lib\\site-packages\\scons-2.3.0\\SCons']
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 The SCons Foundation
The report of the SCons version indicates that both Python and SCons are ready for use. Please make sure that you use SCons version 2.3 or newer, older versions don’t work!
Linux¶
Under Linux, just use the systems package manager in order to install SCons. The package manager will automatically install SCons and all software that SCons depends on, such as Python. For example, under Ubuntu:
> sudo apt-get install scons
Linux Packages¶
Additional software packages must be installed on a Linux system before the Cafu source code can be compiled.
On a fresh, newly installed Debian or Ubuntu system, you’ll need the
following packages. They can be installed at the command prompt with the
apt-get install
command, or via the easy to use “Synaptic Package
Manager”. Similar packages and package managers also exist on RedHat
Linux, SuSE, etc., where you can proceed analogously.
- A graphics driver with 3D hardware acceleration (the right driver is usually auto-detected and installed by the “Driver Manager”).
- build-essential – The compiler and basic tools required to compile C and C++ programs.
- libgtk2.0-dev – Developer files for GTK 2.0, needed for building wxGTK.
- libgl1-mesa-dev and libglu1-mesa-dev – OpenGL developer files, needed for building wxGTK and the Cafu rendering subsystem.
- libxxf86vm-dev – An interface to the XFree86-VidModeExtension extension.
- libasound2-dev – ALSA developer files, needed for building OpenAL-Soft.
Make sure that when you’re done, all packages from the list and their dependencies are installed on your Linux system.
Compiler Setup¶
Cafu can be compiled as 32-bit and 64-bit software on all platforms. The following compilers are supported:
Windows | Remarks |
---|---|
Visual C++ 2015 | You can use the free Express Editions with Cafu. They are available at http://www.microsoft.com/express/vc/ and automatically install the related Microsoft Windows SDK. |
Visual C++ 2013 | |
Visual C++ 2012 | |
Visual C++ 2010 | |
Linux | Remarks |
GCC 4.4+ | The GNU Compiler Collection with its C++ front-end, version 4.4 or any newer version. |
The Cafu-specific compiler setup is fully automatic: No action is required in this step, and you can directly proceed to the next.
Optionally, if you want to change the default settings now or later, here is an overview of how it works:
- When SCons is run in the next step, it first determines if file
Cafu/CompilerSetup.py
already exists. If it doesn’t (e.g. when you do this for the first time), it automatically creates the file as a copy ofCafu/CompilerSetup.py.tmpl
. - Alternatively, you can also copy
Cafu/CompilerSetup.py.tmpl
toCafu/CompilerSetup.py
manually. This is only required once, and only if you want to editCafu/CompilerSetup.py
before SCons is run for the first time. - You can edit
Cafu/CompilerSetup.py
in order to set the compiler and tools that are used to build Cafu, and to set the target architecture (such asx86
orx86_64
) that it is build for. Each setting is well documented, so you should have no problems to make the desired changes. The default settings automatically determine the latest installed compiler and the current architecture, so in most cases the file works out-of-the-box and you have to change nothing at all. Also if you have doubts about the right settings, just continue and use the file as-is.
If you do this for the first time, we recommend that you don’t bother
with Cafu/CompilerSetup.py
at all. Just let the automatism determine
the settings and come back later if desired or required.
64-bit Windows with Visual C++ 2010 or 2012 Express Editions¶
On 64-bit Windows systems, SCons tries to find a 64-bit compiler, but
Visual C++ 2010 Express Edition comes with a 32-bit compiler only. To
tell SCons to use the 32-bit compiler instead, please edit file
Cafu/CompilerSetup.py
as described
here.
Even though the Visual C++ 2012 Express Edition comes with a 64-bit compiler, at this time the same edits must be done for it as well.
Compiling the Source Code¶
You are now ready compile the Cafu source code. At the command prompt,
change into the top-level Cafu
directory (where also the files
CompilerSetup.py(.tmpl)
and SConstruct
are), then start the
compilation with:
> scons
When you do this for the first time, be prepared that it will take a while: Everything is being built from scratch, once for the debug and once for the release build. When you repeat the same command in the future, e.g. after source code changes or updates, only the minimum set of files will be rebuilt and the entire process will complete much faster.
Under Linux, if you have a multi-core system, you can speed this up by having several build jobs run in parallel:
> scons -j N
where N is the maximum number of jobs to start simultaneously. For
example, try -j 4
on a quad-core machine.
Adding Binary Assets¶
You may use the time while the build process is running to download some supplemental files. These files are not strictly required, but will help you with trying out the newly compiled programs as described below.
We recommend that you download and extract the following files:
Download | Extract into |
---|---|
Textures.zip | Cafu/Games/DeathMatch/Textures |
Worlds.zip | Cafu/Games/DeathMatch/Worlds |
Note that although these files are zip archives, they are for use on all platforms (Windows and Linux). With these files, you can immediately run the Cafu engine and see some example worlds when the compilation has finished.
Running the new Programs¶
When the SCons script has finished, all Cafu programs have been built in several variants:
- The
debug
variant contains additional program information and no code optimizations, and is often used during development and for finding and fixing bugs. - The
release
variant has program optimizations enabled in order to maximize the execution speed and contains no debug information. This variant is usually shipped to end users. - The
profile
variant is not built by default. It is similar to therelease
variant, but also has debug information in order to make it suitable for use with a performance profiler.
As all variants can be built for each compiler on each platform, the build process organizes the binaries in a directory hierarchy of the form
build/$platform/$compiler/$variant
That is, if your compiler is Visual C++ 2015 (abbreviated as vc14
)
and your platform is Windows (abbreviated as win32
), and you want to
run the release variant of the new programs, then the related binaries
are relative to the path
build/win32/vc14/release/
Another important consideration is that all programs assume the
top-level Cafu
directory as their working directory.
Combining these facts provides you with several options on how you can run the new programs:
Copy the programs of the platform, compiler and build variant of your choice from
Cafu/build/$platform/$compiler/$variant/…
directly into theCafu
directory. This is what we do for the prepackaged binary releases, as end-users can then simply and directly double-click each executable in the Windows Explorer.Create a Windows link (
.lnk
) or batch (.bat
) file in the proper working directory that calls the desired program in its original location.For developers, the most flexible and recommended approach is to run the program directly from the command prompt: First change the current working directory to
Cafu
, then type the relative path to the desired program (TAB completion – also on Windows – proves to be a great help here!). For example, running the debug version of CaWE under Windows looks like this (note that the example also shows the current working directory at the left, the actual command follows the>
character):D:\Cafu> build\win32\vc14\debug\CaWE\CaWE.exe
Running the release version of Cafu under Linux looks like this:
~/Cafu> ./build/linux2/g++/release/Ca3DE/Cafu
If you have downloaded the binary assets as instructed above, you can
now run your self-compiled Cafu engine e.g. at
build\win32\vc14\release\Ca3DE\Cafu.exe
and try one of the included
demo levels! 😃
What next?¶
Congratulations! When you get here, you have managed to successfully compile the Cafu source code and run the resulting binaries. You may now wish to familiarize yourself more completely with the world of Cafu.
One way to do this is to approach Cafu from a map designers perspective, for example by exploring the Cafu World Editor CaWE. CaWE is not only a map editor, it also contains the GUI editor, a font conversion tool, a materials viewer and a model editor. CaWE can also act as a bridge towards scripting: map scripting, GUI scripting, materials scripting and vegetation scripting are powerful features in Cafu, and it doesn’t stop there!
Programmers should definitively have a look at the other sections in this chapter (At the Core: The Cafu Source Code), such as Starting your own Game. If instead you prefer to dig into the source code right away – just pick your favorite piece of code and start reading and hacking.
Consider Using the Autodesk FBX SDK in order to add support for several additional file formats in the Model Editor.
Or you just browse the files and folders in the Cafu
directory, and
start with whatever you feel most attracted to.
In any case, if you have questions or comments, or if you need help, post a message at the support forums at any time!
How to Submit Patches¶
Cafu is to a community project and we need and very much appreciate your help. Your contributions and especially patches are very important for Cafu. Patches help us to add new features, improve code quality and fix bugs, so we are happy and grateful if you contribute them. 😀
Changing Cafu¶
Please read the Coding Conventions and try to conform to them. In particular, please respect the indentation rules (4 spaces, no TABs) – patches are really difficult to read otherwise.
Provide documentation¶
Bug fixes and elegant program solutions often involve complex code that can be difficult to understand without documentation, and an undocumented new feature is hardly useful to anyone but its author.
Therefore, please provide any required documentation such as source code comments (preferably in familiar and simple Doxygen format), high-level overviews, diagrams, etc. Without documentation, another developer would have to write it, and the patch cannot be applied until he has time to do it.
Make atomic patches¶
A patch should be self-contained – one patch for one thing.
Do not combine multiple new features in a single patch: A patch that adds bitmaps to menu items and fixes a bug in the network code is a bad patch. It should be splitted into two patches.
On the other hand, do not split a single code change into multiple patches: Two patches, one of them being “implementation of new member-functions”, the other “changes in class documentation to accommodate new members” are two bad patches. They are related to one, logically indivisible thing, so they should be in one common patch.
Final Considerations¶
- On Dive-In, we need “How to contribute” / “Fork me on Bitbucket”.
- Why Your Project Doesn’t Need a Contributor Licensing Agreement, http://ebb.org/bkuhn/blog/2014/06/09/do-not-need-cla.html
- https://kernel.org/doc/html/latest/process/submitting-patches.html
Coding Conventions¶
This chapter outlines the basic styles and patterns that are used throughout the Cafu source code.
These guidelines intend to achieve uniform code that is easy to read and maintain by many persons, and should be applied to all newly written code. Old code that does not comply to these rules can still be found in some places, and should be updated to conform to these guidelines on convenient occasions.
Of course, the guidelines described herein are not meant to be exhaustive, and breaking one of these rules in well justified cases (usually to increase readability) is an option.
Control Structures¶
With respect to brackets positioning, indentation and whitespace, control structures are laid out like this:
if (...)
{
...;
}
else if (...)
{
...;
}
else
{
...;
}
for (...; ...; ...)
{
...;
}
while (...)
{
...;
}
do
{
...;
}
while (...);
switch (...)
{
case 1: ...; break;
case 2: ...; break;
case 3: ...; break;
case 4:
...;
break;
case 5:
{
// Extra parentheses are needed for declaring local variables here.
...;
break;
}
default:
...;
break;
}
// "if" variants that are also OK (similar applies to "for" and "while").
if (...) // Omit unnecessary brackets when there is only a single statement.
...;
if (...) ...; // Optionally omit the line break.
if (...) ...; // Special vertical alignment.
else ...;
if (...) ...; // Another special vertical alignment (rare).
else if (...) ...;
else ...;
- Indentation is always 4 spaces (never a TAB (!)).
- Braces are always vertically aligned and each is on a line of its own.
- Note the space in
if (
,for (
,while (
, etc. - Note the space after the semicolons in the
for
statement. - There is one empty line after the closing brace of a multi-line control structure.
- Omit unnecessary braces (but beware of cascaded
if
statements!).
Classes¶
Class declarations follow this pattern:
class MyClassT : public Base
{
public:
MyClassT(float x_=0);
float GetX() const { return x; }
private:
float x;
};
- Note the
T
suffix (short for “Type”) at the end of the class name, indicating a custom type. - Classes that are used as interfaces (ABCs (abstract base classes),
pure-virtual classes) are suffixed by a capital
I
(short for “Interface”) instead. - Definition of methods in-line is OK if the method is short (as
GetX()
above). Most methods should instead be defined as described below.
Methods and Functions¶
The definition of methods and functions follows this pattern:
MyClassT::MyClassT(float x_) : Base(...), x(x_)
{
...;
}
// Alternative constructor definition (preferred!).
MyClassT::MyClassT(float x_)
: Base(...),
x(x_), // Note that indentation is now really 6 spaces.
y(0) // This is because vertical alignment takes precedence in this case.
{
...;
}
float MyClassT::GetX() const
{
return x;
}
- Note the two blank lines between each function definition.
Whitespace¶
As a general rule, use whitespace as you’d use it in written English prose.
That is, do not use whitespace
- with unary operators (e.g.
-
,!
,~
,++
,–
etc.), - with binary arithmetic operators (e.g.
+
,*
, etc.), - with comparison operators (e.g.
==
,>
,>=
, etc.), - with other operators like
=
(assignment),::
(scope resolution),->
(member by pointer), etc.
Not using whitespace around the above mentioned operators (all but unary) works best when your code editor supports syntax highlighting that renders the operators in a style or color that is different from that of the operands. If your code editor doesn’t support highlighting of operators and/or using a space before and after the operator improves the readability of the code, using such whitespace is fine, too.
Use whitespace
- with logical and bitwise operators (e.g.
&&
,||
,&
,|
,^
etc.), - with the ternary conditional operator (
cond ? a : b
), - after commas (e.g. in lists) and semicolons (e.g. in for-loops),
- after keywords (e.g.
if
,for
,while
etc.).
(!) Whitespace must only ever consist of SPACE characters, never of TABs. Setup your text editor to automatically replace one press of the TAB key with the insertion of four SPACE characters. Avoid whitespace at the end of lines, setup your text editor to remove it automatically. Files must end with exactly one newline character.
Indentation¶
For the indentation of blocks of code, we use the “Allman” or “university” style, where the opening and closing brackets are vertically aligned and each bracket is on a separate line as shown in all examples above and below. The enclosed block of code is always indented by four spaces (never by a TAB character!).
Example:
bool IsValidTime(unsigned long Hours, unsigned long Minutes, unsigned long Seconds)
{
if (Hours<24 && Minutes<60 && Seconds<60)
{
// Yes, this is a valid time.
return true;
}
else
{
// No, this is invalid.
return false;
}
}
Of course, in real code this trivial example would be expressed as
bool IsValidTime(unsigned long Hours, unsigned long Minutes, unsigned long Seconds)
{
return Hours<24 && Minutes<60 && Seconds<60;
}
which is both much shorter and more readable.
Vertical Alignment¶
Make use of vertical alignment. Obviously,
std::string Search []={ "mo", "tu", "we" };
std::string Replacement[]={ "Monday", "Tuesday", "Wednesday" };
is more expressive and suggestive than
std::string Search[]={ "mo", "tu", "we" };
std::string Replacement[]={ "Monday", "Tuesday", "Wednesday" };
Parentheses¶
Use parentheses whenever necessary to clarify the operator precedence. Even if a set of parentheses is redundant with respect to the definition of the C++ language, use them e.g. when whitespace alone is insufficient or you had to lookup the proper precedence of not-so-frequently used operators in literature.
Both of these examples are fine:
bool IsValidTime(unsigned long Hours, unsigned long Minutes, unsigned long Seconds)
{
// Okay: Whitespace (and programmer knowledge) alone make operator precedence clear.
// This is the preferred variant.
return Hours<24 && Minutes<60 && Seconds<60;
}
bool IsValidTime2(unsigned long Hours, unsigned long Minutes, unsigned long Seconds)
{
// Also okay: (redundant) parentheses make operator precedence explicitly clear.
return (Hours<24) && (Minutes<60) && (Seconds<60);
}
Avoid “null” parentheses, though. For example
return (Hours<24 && Minutes<60 && Seconds<60);
in the above examples should rarely be written.
Comments¶
All comments are to be written in the English language as error-free as possible, with the proper or at least best possible spelling, grammar and punctuation. Prefer C++ comment styles over C comments:
int yes=1; // Use // to initiate most comments.
int no =0; /* Do NOT write C-sytle one-line comments like this. */
We use Doxygen for writing
code documentation. Doxygen comments are to be written “inline”, that
is, into the header files with the declarations. Within Doxygen
comments, we use the JavaDoc style with the JAVADOC_AUTOBRIEF
option
set to YES
. Prefer /// for multi-line comments above the declaration
and ///< for short single-line comments trailing the declaration.
Conclusions¶
The above presented coding conventions and guidelines are to achieve a uniform and readable code style. Exceptions should be kept to a minimum, but are allowed whenever they increase the readability.
References¶
These references give general information about coding conventions, listed here to help improving this section. The coding conventions that they describe may differ from the conventions established here, and are not meant to apply to Cafu.
Selected Topics¶
Game Development Overview¶
The Cafu Engine can be used both for developing single- or multiplayer games that ship as individual products, as well as for products that support multiple, independent games in a single program that the user can select from at runtime.
For example, after starting the program, the user might choose from a list of online game servers (each possibly running not only different game maps, but entirely different games), or a list of available single-player games, and join one seamlessly without restarting the program.
The fact the multiple games can be present at the same time makes it worthwhile to keep all related files and program code well organized, so that games can be developed and shipped to end users modularly and independently of each other and of the Cafu core engine.
One directory per game¶
In order to achieve these goals, all files, data and program code for a
game are stored in one common directory, which in turn must be a
subdirectory of Games/
.
For an example, see the Games/DeathMatch/
directory of the
DeathMatch example game that ships with Cafu:
(Also see Starting your own Game for help about creating a new game directory.)
Although you’re largely free to organize the contents of the game directory as desired, per convention some of the resource files must be kept under fixed names or in given directories, so that the Cafu Engine can find and load them when it is newly initializing the game.
The following sub-sections list and explain most of these “fixed” files and directories.
GUIs/¶
The graphical user interfaces that are used in a game are kept in
GUIs/
.
GUIs are used both
- in “2D”, e.g. for the main menu, the console window, the “HUD” (head-up display) in the game, etc., as well as
- in “3D”, as parts of the game worlds, that the player can use e.g. to call lifts, to unlock doors, to activate teleporters, or to control any other game script action.
The GUIs kept in GUIs/
are usually “2D” GUIs, and “3D” GUIs that are
universally used in multiple maps. “3D” GUIs that are specific to a
single map can either be stored in GUIs/
as well, or along with the
map in the same directory as the map.
At this time, the following GUIs are automatically loaded by the Cafu Engine:
GUIs/ChatInput.cgui
– implements the text input when the player pressesT
to talk in the game.GUIs/Console.cgui
– implements the in-game command console, opened withF1
.GUIs/MainMenu/MainMenu_main.cgui
– implements the main menu that is shown after program start.
In addition, the DeathMatch game code in
DeathMatch/Code/HumanPlayer.cpp
loads
GUIs/HUD_main.cgui
– implements the players head-up display (cross-hair, ammo count, etc.).
You can replace all these GUIs by providing your own editions in their place, or just copy them from the DeathMatch example game and modify them as you like.
Maps/¶
Contains the map files as saved by the CaWE Map Editor.
You don’t actually have to save your map files in this directory, but we
may merge Maps/
and Worlds/
sometime in the future, and thus
Maps/
is still the recommended place to save .cmap
files.
Materials/¶
All material definitions for the game maps are kept in Materials/
.
Materials are often reused in several maps of a game, and thus
Materials/
is where all map materials are centrally stored.
The CaWE Map Editor loads the material definitions from this folder in
order to provide the map designer with the choices in the Material
Browser dialog. The Cafu Engine loads the material definitions from
Materials/
as well in order to render the materials in the game.
Music/NextTitle.txt¶
Whenever the player enters a new map, the client calls console function
StartLevelIntroMusic()
, that in turn is defined in file
config.lua
in the Cafu top level directory and that uses file
Music/NextTitle.txt
in order to play the next title from the list of
files in Music/
.
Textures/¶
The texture images that the materials in Materials/
are referring to
are stored here.
Worlds/¶
Maps from Maps/
must be “compiled” in order to be used with the Cafu
Engine. Compiling turns a map file (suffix .cmap
) into a world file
(suffix .cw
) and is documented at
Compiling Maps for Cafu.
The world files generated by compiling are stored in Worlds/
, where
the main menu GUI (MainMenu_main.cgui
in the DeathMatch example
game) looks for .cw
files that the player can choose to enter. It
also looks for a matching screenshot image to show with the maps list.
The Worlds/
directory is also the right place for map
scripts:
- A map scripts must be placed into the
Worlds/
directory “next” to the compiled world file. That is, the script must have the same base name as the world, but suffix.lua
instead of.cw
. - The map script is not compiled along with the
.cw
file: You can change it at any time, and the changes become effective as soon as the world is loaded/restarted the next time. In fact, it is even possible to update a map script while the game is running, that is, without interrupting it.
Exploring the code¶
The class hierarchy is shown in Ca3DE/ClassDiagram.dia
Starting your own Game¶
After you took the first steps with the Cafu source code, you’re ready to use it to develop your own game or application.
This section lists the most commonly used methods for starting new projects and explains the required steps to give you a good start.
Cloning DeathMatch¶
The “normal” and recommended way to start a new game is to create a copy of the example game DeathMatch under a different name. This is useful because it immediately provides you with the proper directory structure, working code, and example files.
Creating the clone¶
Creating the copy is straightforward:
- In
Games
, duplicate the directoryDeathMatch
and name the resulting copy as desired, e.g.MyGame
. - Delete the directory
build
inGames/MyGame/Code
.
The second step is necessary because previous builds of DeathMatch may
have created files whose copy can confuse the linker when it is creating
the program library for MyGame
for the first time.
To implement these steps, you can use any method you like, for example a file manager like Windows Explorer, or the command-line. This example shows how you can do it under Linux:
$ cp -r Games/DeathMatch/ Games/MyGame/
$ rm -rf Games/MyGame/Code/build
Using your new game¶
Technically, the above steps are all that is required to create the basis for your new game:
When you re-run SCons as documented at Getting Started with the Cafu Source Code, the code of your new game will automatically be picked up, compiled and linked.
When you start CaWE, it will automatically recognize the new game and show it in the “Configure”, “New Map”, “New GUI”, … etc. dialogs. If “Start Engine” is checked in the “Compile” menu, it will also start the Cafu Engine with the new game.
If you run the Cafu Engine from the command prompt, make sure to add parameter
-svGame MyGame
to the command-line (see below how to get rid of it again).
Tips and Tricks¶
If you want to run your game by default (without
-svGame
), see the section about the variableGameLibs
in fileCompilerSetup.py
: .. code:: python# When you’re developing your own game, you might want to keep game DeathMatch # for reference. Cafu should run your game by default (first in list), whereas # DeathMatch would be readily available via the -svGame command-line option: GameLibs = [“MyGame”, “DeathMatch”]
Note that you have to re-run SCons in order for changes to take effect.
In
MyGame
, some paths in the code and scripts still point toGames/DeathMatch/…
. For the beginning, that’s ok – your game will find some of its resources in game DeathMatch, and you can update these occurrences step by step at any later time (or even intentionally keep things like this).Check out Game Development Overview for details about the files and subdirectories in the new game directory.
Alternatives¶
Here is a list of alternative courses of action that you may want to consider in order to start a new game:
Modifying DeathMatch¶
Working directly with the DeathMatch game “in situ” may seem like a totally silly idea to you, but in some cases it can be a worthwhile consideration nevertheless:
If you want to quickly try something out (e.g. a new entity class), or if you work on something that is not directly or entirely a completely new game (for example, any changes to the core engine), the game DeathMatch might be a welcome testbed.
Also, if you wish to communicate and collaborate with people who are not directly involved with your game code, the DeathMatch code can be a good common ground.
Renaming DeathMatch¶
Renaming DeathMatch, instead of properly copying it, would principally work, if it was not for these factors:
- It does not agree well with version control systems (Git or Subversion). If you follow our recommendation to checkout the Cafu source code from our Git or Subversion repository, so that you can keep track of our latest developments while developing your own game in parallel, then renaming the DeathMatch directory is (indeed not impossible, but) somewhat incompatible with the way how these repositories work.
- Some file paths in code and scripts still point to
Games/DeathMatch/…
. If you rename DeathMatch, all these paths are broken, and your game will not work without fixing them first. If you instead copy DeathMatch, your game will find some of its resources in game DeathMatch, and you can update these occurrences step by step at any later time (or even intentionally keep things like this).
Overall, we recommend not to rename DeathMatch. Better clone it as explained above.
Starting from scratch¶
Creating a new, empty directory in Games/
in order to start from
scratch, then fill it with contents as required, is certainly possible.
Doing this can be a very good choice if your main goal is to learn and understand the technical details from the ground up, or if you only want to have original content in your game right from the start.
In fact, we’re considering complementing the DeathMatch example game with another “Minimal” example game that comes closer to these goals.
If you start with an empty directory,
- your progress will be slower,
- despite the support forums are always available, you should be technically versed enough to cope with most problems and errors,
- be prepared to copy pieces of DeathMatch example code anyway.
Using VSWM¶
The VSWM MOD is old, obsolete, dysfunctional, and a candidate for removal. Not a good basis for a new game. Don’t use it.
Loading game worlds¶
While we have introduced the GUI and entity component systems at several occasions:
- todo
this document provides an overview of how the Cafu programs actually instantiate a game world that is composed of game entities.
All Cafu programs can load game worlds, i.e. the game server, client, the world editor CaWE and the compile tools. We will use the server’s code for reference, but as the code is similar in all programs, we will cover the specifics of other programs as well.
Also use the class diagram in Ca3DE/ClassDiagram.dia
besides this
text for reference.
The server loads a game world by creating a CaServerWorldT
instance
which derives from Ca3DEWorldT
.
The Ca3DEWorldT
’s const WorldT* m_World
member contains the data
from the BSP, PVS and Radiosity compile process: for each static entity,
it has the BSP tree, a collision model, lightmaps, etc. ( (FIXME!)
not only static, but in fact for all entities in the cmap? ) This data
is later correlated to (and becomes a component of) the main entity
instances cf::GameSys::EntityT
.
The Ca3DEWorldT
keeps an instance of a cf::UniScriptStateT
. This
script state is a Lua instance to which later our objects are bound so
that we then can write code such as:
local new_ent = world:new("EntityT", "left_wing")
Door:AddChild(new_ent)
new_ent:GetTransform():set("Origin", 480, -352, 104)
Note that both game entities and GUI windows, our two sibling
component systems, can be instantiated in the script state of a
Ca3DEWorldT
.
Using the Autodesk FBX SDK¶
When
you build Cafu from source, support for several file formats is provided
by Cafu’s own source code so that the Model Editor can import static and
animated models in the most important file formats.
Optionally, it is possible to have the build scripts account for and use the Autodesk FBX SDK in order enable the Model Editor to import model files in these additional file formats as well:
- Autodesk FBX (
.fbx
), version 6.0 to 7.2 - Autodesk AutoCAD DXF (
.dxf
), version 13 and earlier - Collada DAE (
.dae
), version 1.5 and earlier - 3D Studio 3DS (
.3ds
), all versions - Alias OBJ (
.obj
), all versions
The FBX SDK is a separate download from Autodesk that we cannot distribute together with Cafu: The combined file size for all platforms is massive, Autodesk prefers that software vendors don’t redistribute their SDK and in fact requires prior written permission, and we’re happy to maintain a certain degree of independence, for example when we want to use Cafu with compilers or on platforms where the FBX SDK is not available.
Therefore, we made the use of the Autodesk FBX SDK very easy, but entirely optional. If you don’t use it, all that you’re missing is that the Model Editor cannot load the above mentioned file formats. (When we make official binary releases of Cafu, we always ship with FBX support enabled.)
Follow these steps in order to activate support for FBX:
- Download the Autodesk FBX SDK from http://www.autodesk.com/fbx
- The download requires a one-time registration, but it’s free.
- You just need the FBX SDK, not the FBX Extensions SDK.
- At this time, we use version 2017.1 of the FBX SDK, but any later version should work as well.
- Run the installer to extract the SDK contents into a convenient
location. Their installer is exceptionally nice, it neither modifies
the Start Menu nor the Windows Registry, but just extracts the files
into a directory.
- Assuming that your top level Cafu source code directory is
Cafu/
, you can directly install the FBX SDK intoCafu/ExtLibs/fbx/
. Make sure that the installer doesn’t automatically append another directory for the SDK version, and if it asks if you would like to keep a copy of the old FBX installation, answer “No” (otherwise it first renamesCafu/ExtLibs/fbx/
toCafu/ExtLibs/fbx.old/
, creating an (easily fixed) problem if you use Git). - Alternatively, just install the FBX SDK into a convenient location
first (e.g. into a temporary directory or the default directory
suggested by the installer), then copy or move the contents into
Cafu/ExtLibs/fbx/
. (Under Linux, we recommend to not install into the suggested/usr
directory. Better install into a temporary directory in your home folder, no root privileges required.)
- Assuming that your top level Cafu source code directory is
- As a result from the previous step, make sure that you now have
directories
examples
,include
andlib
(and possibly others) immediately belowCafu/ExtLibs/fbx/
. - (Re-)Run SCons as described at Getting Started with the Cafu Source Code in order to automatically recompile with FBX support enabled.