1. Introduction

Logging can be initialized by InitializeLog. But if you follow our advised structure of a cross-platform project, then it is automatically done for you, in the initialization of castleautogenerated.pas unit, for all the platforms. So, no need to worry about this.

Some engine functions also automatically write to this log. For example, creating the OpenGL context logs the OpenGL and GPU features detected.

2. An example

{$ifdef MSWINDOWS} {$apptype GUI} {$endif}

uses CastleLog, CastleWindow, CastleColors, CastleControls;
  Window: TCastleWindow;
  Lab: TCastleLabel;

  WritelnLog('My Log Message');
  WritelnLog('My Category', 'My Log Message');
  WritelnWarning('My Warning');

  // display the LogOutput value in a window
  Window := TCastleWindow.Create(Application);

  Lab := TCastleLabel.Create(Application);
  Lab.Caption := 'Logging to ' + LogOutput;
  Lab.Color := White;


The category 'My Category', used by the call WritelnLog('My Category', 'My Log Message'), is useful to spot/filter your log messages. There are no rules about what categories are available, you’re free to just invent own category names and use them.

3. Capturing

You can capture the log messages by adding a callback to the TCastleApplicationProperties.OnLog list. Like this:

ApplicationProperties.OnLog.Add({$ifdef FPC}@{$endif} MyLogCallback);

See examples/network/remote_logging for an example that captures log messages, and sends them through a network (HTTP POST) to a server.

4. Where is the log stored?

  • When running from CGE editor, the log is displayed in the bottom editor panel.

  • When running using CGE build tool castle-engine run command, the log is displayed as the standard output.

  • When running the application as a normal user:

    • On Unix (Linux, macOS…​), and for Windows console applications, logging by default goes to the standard output. This is the standard behavior for Unix and console apps.

      Users can redirect it by running the application from the command-line like my_game > log_file.log. The nice thing about this approach is that it avoids users asking questions "where is the log file". Users explicitly decide where the log goes.

      If you don’t want to produce log to the standard output (and prefer to always log to file, as described below) then set LogEnableStandardOutput to false.

    • For Windows GUI applications, or if you set LogEnableStandardOutput := false, we log to the file in the user config directory.

      • On Windows the file name looks like C:\Users\<user-name>\AppData\Local\<application-name>\<application-name>.log.

      • On Unix the file name looks like $HOME/.config/<application-name>\<application-name>.log.

      The exact logic to determine the user config directory follows FPC GetAppConfigDir. This uses the appropriate OS-specific mechanism (e.g. asks the Windows API function, or follows xdg-user-dirs conventions). You can display the LogOutput value to show user on screen where is the log file.

    • On Android the log goes to the standard device log. It that can be viewed using various Android tools, like adb logcat.

    • On iOS, Nintendo Switch it goes to the standard log facility for these devices.

  • User can call the application with --log-file=c:/tmp/my_log_name.txt command-line option to set the log filename explicitly.

    This sets the LogFileName variable which will be used by subsequent InitializeLog. This command-line option is handled when you call Application.ParseStandardParameters, which in turn is done automatically in the castleautogenerated.pas unit. So you just don’t need to do anything to make this possible.

  • Deprecated: If you write your own main program code (not using our castleautogenerated.pas unit) then you call InitializeLog explicitly. You can then pass a parameter to InitializeLog to write log to any stream. You can also set LogFileName variable before calling the InitializeLog. This way you force using specific filename for logging, overriding the OS-specific auto-detection mechanism described above.

To improve this documentation just edit this page and create a pull request to cge-www repository.