# How to identify events in the API Calls window (Profiler)

**URL:** <https://qa.fmod.com/t/how-to-identify-events-in-the-api-calls-window-profiler/17792>\
**Category:** FMOD Studio\
**Tags:** ue4\
**Created:** [October 14, 2021, 1:34pm UTC](https://qa.fmod.com/t/how-to-identify-events-in-the-api-calls-window-profiler/17792 "2021-10-14T13:34:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![chrisjdarcy](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/chrisjdarcy/32/172_2.png) [@chrisjdarcy](https://qa.fmod.com/u/chrisjdarcy)\
**Post date:** [October 14, 2021, 1:34pm UTC](https://qa.fmod.com/t/how-to-identify-events-in-the-api-calls-window-profiler/17792/1 "2021-10-14T13:34:43Z")

</div>

How do we identify events with the API Calls window?

There’s only numbers in the arguments for the calls.

---

<div class="post-metadata">

**Author:** ![Alcibiade](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/alcibiade/32/4284_2.png) [@Alcibiade](https://qa.fmod.com/u/Alcibiade)\
**Post date:** [October 14, 2021, 4:52pm UTC](https://qa.fmod.com/t/how-to-identify-events-in-the-api-calls-window-profiler/17792/2 "2021-10-14T16:52:33Z")

</div>

I don’t think that’s possible, but that would be handy…

---

<div class="post-metadata">

**Author:** ![mathew](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/mathew/32/431_2.png) [@mathew](https://qa.fmod.com/u/mathew)\
**Post date:** [October 14, 2021, 9:51pm UTC](https://qa.fmod.com/t/how-to-identify-events-in-the-api-calls-window-profiler/17792/3 "2021-10-14T21:51:50Z")

</div>

Navigation of the API log is not super easy, you might need to navigate into the [project]\Metadata\ProfilerSession folder and look at the .txt capture in a text editor.

The first argument to the EventInstance functions is its ID, to match that ID back to the EventDescription GUID look for the first instance of that ID in the log, it should be a EventDescription::createInstance call, where the ID is the second argument. The first argument to that call is the EventDescription ID. Same process, find the first instance of that ID, it should be a Bank::getEventListItem call with the ID as the last argument. The first argument is the Event guid which you can copy and paste into the event browser to find the event in question.

I hadn’t considered it before, but having the IDs as hyperlinks that jump to their respective editor, i.e. EventInstance IDs jump to the event browser, BusInstances jump to the mixer could be a pretty nice feature.

---

<div class="post-metadata">

**Author:** ![tb-ktracing](https://avatars.discourse-cdn.com/v4/letter/t/898d66/32.png) [@tb-ktracing](https://qa.fmod.com/u/tb-ktracing)\
**Post date:** [July 28, 2022, 2:28pm UTC](https://qa.fmod.com/t/how-to-identify-events-in-the-api-calls-window-profiler/17792/4 "2022-07-28T14:28:11Z")

</div>

Hello,  
I had to use recently the API log and it would be great if, next to the ids, the name of the event or bus could be added and also it would be a good information to add, the call origin: if the call was made internaly (from an event command or virtualization manager) or with the API from game code.

---

<div class="post-metadata">

**Author:** ![mathew](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/mathew/32/431_2.png) [@mathew](https://qa.fmod.com/u/mathew)\
**Post date:** [July 28, 2022, 11:05pm UTC](https://qa.fmod.com/t/how-to-identify-events-in-the-api-calls-window-profiler/17792/5 "2022-07-28T23:05:42Z")

</div>

We do have plans for making the API view richer but nothing immediately scheduled.

As for your comment about command instruments and the like, the API capture only includes commands issued by the game, not internal commands such as command instruments. It’s our public API that does the capturing and all internal operations do not use that, hence they aren’t recorded.

---

<div class="post-metadata">

**Author:** ![Alcibiade](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/alcibiade/32/4284_2.png) [@Alcibiade](https://qa.fmod.com/u/Alcibiade)\
**Post date:** [June 17, 2025, 12:12am UTC](https://qa.fmod.com/t/how-to-identify-events-in-the-api-calls-window-profiler/17792/6 "2025-06-17T00:12:26Z")

</div>

I just made (with chatGPT) a python script which make the logs way more readable, by referencing every event and instances. It duplicates and annotates each log file in the profiler folder, based on the GUIDs file.

For exemple,

```auto
Bank::getEventListItem, 2097152, 30, {a6d54fd3-bae9-47e0-ae2c-99953aa66e4f}, 2103040
EventDescription::createInstance, 2103040, 2109184
EventInstance::start, 2109184
EventInstance::stop, 2109184, 1

```

becomes

```auto
Bank::getEventListItem, 2097152, 30, {a6d54fd3-bae9-47e0-ae2c-99953aa66e4f}, 2103040 -- event:/UI/characterSelected
EventDescription::createInstance, 2103040, 2109184 -- createInstance characterSelected #3
EventInstance::start, 2109184 -- start characterSelected #3
EventInstance::stop, 2109184, 1 -- stop characterSelected #3

```

> **Python script**
>
> ```auto
> import os
> import re
> from pathlib import Path
> 
> # --- Configuration des chemins ---
> AUDIO_DIR = Path(r"C:\Program Files (x86)\Steam\steamapps\common\zodiaclegion\assets\audio")
> GUIDS_FILE = AUDIO_DIR / "GUIDs.txt"
> PROFILER_DIR = Path(r"C:\Users\Alcibiade\Documents\FMOD Studio\Zodiac Legion\Metadata\ProfilerSession")
> 
> # --- Chargement du mapping GUID → chemin FMOD depuis GUIDs.txt ---
> def load_guid_map(path):
> guid_map = {}
> pattern = re.compile(r"\{([0-9a-fA-F\-]+)\}\s+(.+)")
> with open(path, 'r', encoding='utf-8') as f:
> for line in f:
> m = pattern.match(line.strip())
> if m:
> guid = m.group(1).lower()
> fmod_path = m.group(2).strip()
> guid_map[guid] = fmod_path
> return guid_map
> 
> # --- Extraction du short name à partir du chemin FMOD ---
> def short_name(path):
> return path.rstrip('/').split('/')[-1]
> 
> # --- Fonction pour aligner le commentaire à la colonne 55 ---
> def align_comment(line, comment):
> if len(line) < 55:
> return line + ' ' * (55 - len(line)) + comment
> else:
> return line + ' ' + comment
> 
> # --- Annotation d’un seul fichier log ---
> def annotate_file(log_path, guid_map):
> handle_to_path = {} # desc_handle et inst_handle → fmod_path
> instance_counters = {} # fmod_path → nombre d’instances créées
> handle_to_instance = {} # inst_handle → numéro d’instance
> 
> re_get = re.compile(r"Bank::getEventListItem.*\{([0-9a-fA-F\-]+)\},\s*(\d+)")
> re_create = re.compile(r"EventDescription::createInstance.*,\s*(\d+)\s*,\s*(\d+)")
> re_eventinst= re.compile(r"EventInstance::(\w+).*?,\s*(\d+)")
> 
> out_lines = []
> with open(log_path, 'r', encoding='utf-8') as f:
> for raw in f:
> content = raw.rstrip('\n')
> 
> # 1) Bank::getEventListItem → commenter full path
> m = re_get.search(content)
> if m:
> guid, desc_handle = m.group(1).lower(), m.group(2)
> if guid in guid_map:
> fmod_path = guid_map[guid]
> handle_to_path[desc_handle] = fmod_path
> comment = f"-- {fmod_path}"
> out_lines.append(align_comment(content, comment) + "\n")
> else:
> out_lines.append(content + "\n")
> continue
> 
> # 2) createInstance → commenter full path + #N
> m = re_create.search(content)
> if m:
> desc_handle, inst_handle = m.group(1), m.group(2)
> fmod_path = handle_to_path.get(desc_handle, "")
> cnt = instance_counters.get(fmod_path, 0) + 1
> instance_counters[fmod_path] = cnt
> handle_to_instance[inst_handle] = cnt
> handle_to_path[inst_handle] = fmod_path
> name = short_name(fmod_path)
> comment = f"-- createInstance {name}" + (f" #{cnt}" if cnt > 1 else "")
> out_lines.append(align_comment(content, comment) + "\n")
> continue
> 
> # 3) EventInstance::<command> → commenter <command> <short_name>#N
> m = re_eventinst.search(content)
> if m:
> cmd, inst_handle = m.group(1), m.group(2)
> fmod_path = handle_to_path.get(inst_handle, "")
> cnt = handle_to_instance.get(inst_handle, 1)
> name = short_name(fmod_path)
> comment = f"-- {cmd} {name}" + (f" #{cnt}" if cnt > 1 else "")
> out_lines.append(align_comment(content, comment) + "\n")
> continue
> 
> # 4) autres lignes → pas d’annotation
> out_lines.append(content + "\n")
> 
> out_path = log_path.with_name(log_path.stem + "_annotated.txt")
> with open(out_path, 'w', encoding='utf-8') as out_f:
> out_f.writelines(out_lines)
> 
> print(f" → créé : {out_path.name}")
> 
> # --- Parcours des logs + ouverture dossier ---
> def main():
> if not GUIDS_FILE.is_file():
> print("Erreur : GUIDs.txt introuvable à", GUIDS_FILE)
> return
> global guid_map
> guid_map = load_guid_map(GUIDS_FILE)
> 
> for txt in PROFILER_DIR.rglob("*.txt"):
> if "annotated" in txt.stem.lower():
> continue
> print("Traitement de", txt.name)
> annotate_file(txt, guid_map)
> 
> os.startfile(str(PROFILER_DIR))
> 
> if __name__ == " __main__":
> main()
> 
> ```

Of course, change the paths at the beginning, expand, and translate french terms as you want!  
By the way, why is this basic stuff just not built in by default?
