remove bracket
[xonotic/xonotic.wiki.git] / Programming-Tips.md
1 ### Debug prints
2
3 Use `con_notify 4` together with `LOG_INFOF("my_var: %s", my_var);` (`%s` string, `%f` float, `%d` integer, `%v` vector) to see debug output without opening the console. Type `con_notify` and press `<TAB>` to see descriptions and more options (or use `apropos con_notify`).
4
5 You can draw text anywhere on the map using `debug_text_3d(world_coords, message);` from `common/debug.qh`.
6
7 ### Multiple clients + clean config
8
9 If you need 2 players for debugging, you can launch another client locally:
10  - use -sessionid (e.g. `./all run -sessionid testing`) to keep your config
11  - use -userdir (e.g. `./all run -userdir ~/.xonotic-testing +name tester +cl_allow_uid2name 0`) to get a clean config (`+cl_allow_uid2name 0` to avoid an annoying popup). You can set whatever cvar on start with `+cvar_name value`.
12
13 ### Testing with bots
14
15 You can prevent bots from firing with `bot_nofire 1` or stop them completely with `bot_cmd * pause` (unstop them with `bot_cmd * continue`). With `sv_cheats 1` (takes effect next match), you can drag them around (default key V or 'drag object' in menu).
16
17 Note that `sv_cheats 1` prevents bots from spawning in the campaign (should you decide to put it in your `autoexec.cfg` and later wonder why the campaign is broken).
18
19 ### Debugging
20
21 Useful commands to debug qc code:
22 ```
23 prvm_breakpoint : marks a statement or function as breakpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear breakpoint
24
25 prvm_edict    : print all data about an entity number in the selected VM (server, client, menu)
26 prvm_edictget : retrieves the value of a specified property of a specified entity in the selected VM (server, client menu) into a cvar or to the console
27 prvm_edicts   : prints all data about all entities in the selected VM (server, client, menu)
28 prvm_edictset : changes value of a specified property of a specified entity in the selected VM (server, client, menu)
29 prvm_edictwatchpoint : marks an entity field as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint
30
31 prvm_global    : prints value of a specified global variable in the selected VM (server, client, menu)
32 prvm_globalget : retrieves the value of a specified global variable in the selected VM (server, client menu) into a cvar or to the console
33 prvm_globals   : prints all global variables in the selected VM (server, client, menu)
34 prvm_globalset : sets value of a specified global variable in the selected VM (server, client, menu)
35 prvm_globalwatchpoint : marks a global as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint
36 ```
37
38 Examples:  
39 Print to console origin of entity number 1: `prvm_edictget server 1 origin`  
40 Save to a cvar origin of entity number 1: `prvm_edictget server 1 origin my_cvar`  
41 Set a custom origin for entity number 1: `prvm_edictset server 1 origin "100 200 0"`
42
43 Setting view angles requires a particular trick, we also need to set fixangle to true in the same server frame:
44 `prvm_edictset server 1 fixangle 1; prvm_edictset server 1 angles "20 -90 0"`
45
46 Print to console vid_conheight client global: `prvm_edictget client vid_conheight`
47
48 "Break" on statement: `prvm_breakpoint server 12345`  
49 "Break" on function: `prvm_breakpoint server ClientConnect`  
50 Watch for global change: `prvm_globalwatchpoint server time`  
51 Watch for entity field change: `prvm_edictwatchpoint server 1 health`  
52
53 There can be only one of each kind. To clear, do:
54 ```
55 prvm_breakpoint server
56 prvm_globalwatchpoint server
57 prvm_edictwatchpoint server
58 ```
59
60 ### Tool to find C symbols, functions, declarations and definitions inside source code
61
62 For this purpose it's possible to use a text-based tool called [Cscope](https://en.wikipedia.org/wiki/Cscope) together with a GUI (it can be either an application or a plugin for a text editor).
63
64 #### Download / Installation
65
66 * Download and install cscope with `pacman -S cscope`  
67 Windows users must download the Windows version of cscope from https://code.google.com/archive/p/cscope-win32/downloads and put it into the main xonotic repo directory. The mingw version can't be used as it puts Unix paths into the generated indices, making them unusable.
68
69 * Download and install a cscope GUI or a plugin for your text editor / IDE.
70   * For [jEdit](http://www.jedit.org) there is a plugin called [CscopeFinder](http://plugins.jedit.org/plugins/?CscopeFinder).
71   * For [SublimeText](https://www.sublimetext.com) there is [SublimeCscope](https://github.com/jgust/SublimeCscope)
72   * For [Atom](https://atom.io/) there is [atom-cscope](https://atom.io/packages/atom-cscope)
73
74 * If you don't use Atom, you also need to copy ~~[cscope_createindex.sh](uploads/17c725e19be8f4935c30c2506e168405/cscope_createindex.sh)(old version)~~ [cscope_createindex.sh](uploads/451835f6b1894145af06050915256048/cscope_createindex.sh) into the main xonotic repo directory.
75
76
77 #### Configuration
78
79 * Configure your plugin if needed:  
80   * jEdit's CscopeFinder settings:  
81   set cscope.out as cscope index filename.  
82
83   * SublimeCscope user settings (with Windows executable as example):
84         ```
85                 "executable": "C:\\xonotic\\cscope.exe",
86                 "prompt_before_searching": false,
87         ```
88
89   * atom-cscope settings:
90   1. set the full path of cscope binary, e.g. C:\xonotic\cscope.exe (with Windows executable as example)  
91   1. add .qc and .qh to source file extensions (".c .cc .cpp .h .hpp .qc .qh")
92   1. you also need to create projects for darkplaces and xonotic/data/xonotic-data.pk3dir/qcsrc folders (toggle tree-view with `Ctrl + \`, right-click there and select "Add Project Folder")
93
94 * Run `cscope_createindex.sh` to build cscope indices for both game (QC code) and Darkplaces (C code). This step must be repeated every time you do some code changes.
95
96 * Some plugins assume that your index file is generated with compression turned on (SublimeCscope's case). In this case `cscope_createindex.sh` can be instructed to use compression by changing `compress=false` to `compress=true`.
97
98 * With Atom you can build cscope indices in the atom-cscope window (open with `Ctrl + Alt + o`) by clicking the flash icon.
99
100 #### Usage
101
102 * jEdit: select a word in the editor, right-click and select "Find this C symbol" or another "Find ..." entry (if you don't see these entries you should add them in the context menu settings).
103 * SublimeText: select a word in the editor, right-click and select "Look up symbol" or another "Look up ..." entry.
104 * Atom: open atom-cscope window (`Ctrl + Alt + o`) and type a symbol that you want to search.
105
106
107 ### QC syntax highlighting:
108
109 * For jEdit: [qc.xml](https://gitlab.com/terencehill/qc-syntax-highlighting-for-jedit/blob/master/qc.xml)
110 * For Kate: [qc.xml](https://gist.github.com/DefaultUser/998f030ab41a9e8edf4a9f8e703c6350)