TSWoW can be built with support for tracy, the C++ frame profiler.
When enabled, tracy can be used to track function calls both in the core and in your own scripts using very simple commands. The server can then be connected and viewed in realtime by the tracy server application
This article will outline specific configurations needed to make tracy work with tswow, but for general usage and how to set up the tracy server you can refer to the official tracy documentation.
Note: If you are using an official tswow repack, tracy should be automatically enabled for all core categories since version 0.15.
To use tracy at all, it must be enabled when you build the core. To do this, you must supply a tracy flag either to the npm run build
command or the build trinitycore-xxx
interactive command:
npm run build tracy=*
build trinitycore-relwithdebinfo tracy=*
By using the argument tracy=*
, you enable tracy profiling for all builtin categories. You can also choose to specify exactly what builtin categories you want to profile by default:
For example, to build tswow and only profile world update events, you would use the tracy flag tracy=world
, and for building world and map updates you would use the flag tracy=world,map
To completely skip profiling all builtin categories (useful when you only want to profile your own livescripts, you can use the plain tracy
flag:
npm run build tracy
build trinitycore-relwithdebinfo tracy
You can easily add new profile points to the core using the TC_ZONE_SCOPED
and TS_ZONE_SCOPED_N
(for named scopes) macros, defined in TSProfile.h. As its argument, provide the profiling category that fits best, e.g. WORLD_PROFILE
or MAP_PROFILE
.
For some examples, see World.cpp and Map.cpp
Feel free to use the entity
, spell
or database
categories if you think they fit your use.
Builtin categories are all defined in TSProfile.h, and all you need to create a new category can be found in that file. Build scripts automatically parse this file to figure out what profiling categories exists, so make sure to follow the formatting used by the other categories (ifdef PROFILE_X
, X_PROFILE
etc.).
Similarly to when you build the core, you enable tracy when building livescripts using the tracy
flag. In livescripts it is possible to define your own profiling categories, and similarly to core categories you can choose what categories should be enabled:
build scripts tracy=*
build scripts tracy=myCategory
First, we need to create a profiling category and define a color to use for it. Note that the variable name we assign this category to is the name we use to filter it.
const MY_PROFILING_CATEGORY = TS_ZONE_CATEGORY(0xff0000)
With this category, we can now start placing TS_ZONE_SCOPED
declarations at the top of function calls we want profiled under it:
export function MyExpensiveFunctionCall()
{
TS_ZONE_SCOPED(MY_PROFILING_CATEGORY)
}
If we want to profile specific events without a function call, it is a good idea to instead use the TS_ZONE_SCOPED_N
macro to give the profiling point a descriptive name, since the event itself is placed inside an anonymous lambda:
export function Main(events: TSEvents) {
events.Player.OnSomeExpensiveEvent(() => {
TS_ZONE_SCOPED_N(MY_PROFILING_CATEGORY, "Player.OnSomeExpensiveEvent");
});
}
Note that since the TS_ZONE_SCOPED
family of functions are special compile-time macros, you cannot give them variables (other than globally defined profiling categories) as parameters.
See the official tracy documentation