]> de.git.xonotic.org Git - xonotic/xonotic.wiki.git/blob - Programming-Tips.md
Update Programming Tips: add aliases to some prvm_* commands
[xonotic/xonotic.wiki.git] / Programming-Tips.md
1 ### Faster compiling and reloading of QuakeC\r
2 \r
3 You can use `QCCFLAGS_WERROR=""` to let the build succeed even with some warnings and `ZIP=:` to skip compressing the resulting csprogs.dat (client gamecode) into a pk3. A compressed csprogs.dat is only useful to increase download speed of such file if you host an online dedicated server.\r
4 \r
5 `QCCFLAGS_WERROR="" ZIP=: ./all compile`\r
6 \r
7 Server and menu code produce progs.dat and menu.dat respectively.\r
8 \r
9 Compiling the Xonotic game code without trying to compile the engine code reduces compile time a little bit, in the case you aren't interested in changing the engine code. You can do so by running this command from the xonotic-data.pk3dir directory:\r
10 \r
11 `make qc -j4`\r
12 \r
13 where `-j4` is an option that lets you use up to 4 CPU cores for the compilation (it's enabled by default in `./all compile`). If you want you can run `make all -j4` to enable csprogs.dat compression.\r
14 \r
15 To test the QC client and server programs you don't need to restart Xonotic, you just have to start a new game with `map <mapname>` (depending on how you launch Xonotic you may need to use `fs_rescan; map <mapname>`).\r
16 \r
17 To test the QC menu program, you just have to restart the menu by executing `menu_restart` in the console.\r
18 \r
19 ### Debug prints\r
20 \r
21 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`).\r
22 \r
23 You can draw text anywhere on the map using `debug_text_3d(world_coords, message);` from `common/debug.qh`.\r
24 \r
25 ### Multiple clients + clean config\r
26 \r
27 If you need 2 players for debugging, you can launch another client locally:\r
28 - use -sessionid (e.g. `./all run -sessionid testing`) to keep your config\r
29 - use -userdir (e.g. `./all run -userdir ~/.xonotic-testing +name tester +cl_allow_uid2name 0`) to get a clean config (if you delete the dir before each use)\r
30   - you can set any cvar or run any command on start with `+cvar_name value`\r
31     - `+name tester` avoids the nick selection dialog\r
32     - `+cl_allow_uid2name 0` avoids an annoying popup \r
33 \r
34 ### Testing with bots\r
35 \r
36 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).\r
37 \r
38 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).\r
39 \r
40 ### Debugging\r
41 \r
42 Useful commands to debug qc code:\r
43 ```\r
44 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\r
45 \r
46 prvm_edict    : print all data about an entity number in the selected VM (server, client, menu)\r
47 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\r
48 prvm_edicts   : prints all data about all entities in the selected VM (server, client, menu)\r
49 prvm_edictset : changes value of a specified property of a specified entity in the selected VM (server, client, menu)\r
50 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\r
51 \r
52 prvm_global    : prints value of a specified global variable in the selected VM (server, client, menu)\r
53 prvm_globalget : retrieves the value of a specified global variable in the selected VM (server, client menu) into a cvar or to the console\r
54 prvm_globals   : prints all global variables in the selected VM (server, client, menu)\r
55 prvm_globalset : sets value of a specified global variable in the selected VM (server, client, menu)\r
56 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\r
57 ```\r
58 \r
59 Examples:  \r
60 Print to console origin of entity number 1: `prvm_edictget server 1 origin`  \r
61 Save to a cvar origin of entity number 1: `prvm_edictget server 1 origin my_cvar`  \r
62 Set a custom origin for entity number 1: `prvm_edictset server 1 origin "100 200 0"`\r
63 \r
64 Setting view angles requires a particular trick, we also need to set fixangle to true in the same server frame:\r
65 `prvm_edictset server 1 fixangle 1; prvm_edictset server 1 angles "20 -90 0"`\r
66 \r
67 Print to console vid_conheight client global: `prvm_edictget client vid_conheight`\r
68 \r
69 "Break" on statement: `prvm_breakpoint server 12345`  \r
70 "Break" on function: `prvm_breakpoint server ClientConnect`  \r
71 Watch for global change: `prvm_globalwatchpoint server time`  \r
72 Watch for entity field change: `prvm_edictwatchpoint server 1 health`  \r
73 \r
74 There can be only one of each kind. To clear, do:\r
75 ```\r
76 prvm_breakpoint server\r
77 prvm_globalwatchpoint server\r
78 prvm_edictwatchpoint server\r
79 ```\r
80 \r
81 As of Xonotic 0.8.6 many of those commands are available via shorter aliases:\r
82 \r
83 ```\r
84 // breakpoint\r
85 alias ps_b "prvm_breakpoint server ${* ?}"\r
86 alias pc_b "prvm_breakpoint client ${* ?}"\r
87 alias pm_b "prvm_breakpoint menu ${* ?}"\r
88 \r
89 // entity\r
90 alias ps_e "prvm_edict server ${* ?}"\r
91 alias pc_e "prvm_edict client ${* ?}"\r
92 alias pm_e "prvm_edict menu ${* ?}"\r
93 \r
94 // field get\r
95 alias ps_fg "prvm_edictget server ${* ?}"\r
96 alias pc_fg "prvm_edictget client ${* ?}"\r
97 alias pm_fg "prvm_edictget menu ${* ?}"\r
98 // field set\r
99 alias ps_fs "prvm_edictset server ${* ?}"\r
100 alias pc_fs "prvm_edictset client ${* ?}"\r
101 alias pm_fs "prvm_edictset menu ${* ?}"\r
102 // field watchpoint\r
103 alias ps_fw "prvm_edictwatchpoint server ${* ?}"\r
104 alias pc_fw "prvm_edictwatchpoint client ${* ?}"\r
105 alias pm_fw "prvm_edictwatchpoint menu ${* ?}"\r
106 \r
107 // global get\r
108 alias ps_gg "prvm_globalget server ${* ?}"\r
109 alias pc_gg "prvm_globalget client ${* ?}"\r
110 alias pm_gg "prvm_globalget menu ${* ?}"\r
111 // global set\r
112 alias ps_gs "prvm_globalset server ${* ?}"\r
113 alias pc_gs "prvm_globalset client ${* ?}"\r
114 alias pm_gs "prvm_globalset menu ${* ?}"\r
115 // global watchpoint\r
116 alias ps_gw "prvm_globalwatchpoint server ${* ?}"\r
117 alias pc_gw "prvm_globalwatchpoint client ${* ?}"\r
118 alias pm_gw "prvm_globalwatchpoint menu ${* ?}"\r
119 ```\r
120 \r
121 \r
122 ### Doxygen\r
123 \r
124 Incomplete [Doxygen documentation](https://timepath.github.io/scratchspace/index.html) is generated as part of CI on [xonotic-data.pk3dir](https://gitlab.com/xonotic/xonotic-data.pk3dir) - you can search functions, "classes", globals, etc.\r
125 \r
126 Note that it might be incomplete or incorrect because [Doxygen](https://www.doxygen.nl) doesn't understand all of QC's constructs and our code heavily uses macros. See the `doxygen` section of the [CI file](https://gitlab.com/xonotic/xonotic-data.pk3dir/blob/master/.gitlab-ci.yml) for details what's missing.\r
127 \r
128 ### Tool to find C symbols, functions, declarations and definitions inside source code\r
129 \r
130 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).\r
131 \r
132 ##### Download / Installation\r
133 \r
134 * Download and install cscope with `pacman -S cscope`  \r
135 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.\r
136 \r
137 * Download and install a cscope GUI or a plugin for your text editor / IDE.\r
138   * For [jEdit](http://www.jedit.org) there is a plugin called [CscopeFinder](http://plugins.jedit.org/plugins/?CscopeFinder).\r
139   * For [SublimeText](https://www.sublimetext.com) there is [SublimeCscope](https://github.com/jgust/SublimeCscope)\r
140   * For [Atom](https://atom.io/) there is [atom-cscope](https://atom.io/packages/atom-cscope)\r
141 \r
142 * 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.\r
143 \r
144 \r
145 ##### Configuration\r
146 \r
147 * Configure your plugin if needed:  \r
148   * jEdit's CscopeFinder settings:  \r
149   set cscope.out as cscope index filename.  \r
150 \r
151   * SublimeCscope user settings (with Windows executable as example):\r
152         ```\r
153                 "executable": "C:\\xonotic\\cscope.exe",\r
154                 "prompt_before_searching": false,\r
155         ```\r
156 \r
157   * atom-cscope settings:\r
158   1. set the full path of cscope binary, e.g. C:\xonotic\cscope.exe (with Windows executable as example)  \r
159   1. add .qc and .qh to source file extensions (".c .cc .cpp .h .hpp .qc .qh")\r
160   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")\r
161 \r
162 * 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.\r
163 \r
164 * 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`.\r
165 \r
166 * With Atom you can build cscope indices in the atom-cscope window (open with `Ctrl + Alt + o`) by clicking the flash icon.\r
167 \r
168 ##### Usage\r
169 \r
170 * 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).\r
171 * SublimeText: select a word in the editor, right-click and select "Look up symbol" or another "Look up ..." entry.\r
172 * Atom: open atom-cscope window (`Ctrl + Alt + o`) and type a symbol that you want to search.\r
173 \r
174 \r
175 ### QC syntax highlighting:\r
176 \r
177 * terencehill's version for jEdit: [qc.xml](https://gitlab.com/terencehill/qc-syntax-highlighting-for-jedit/blob/master/qc.xml)\r
178 * EACFreddy's version for Kate: [qc.xml](https://gist.github.com/DefaultUser/998f030ab41a9e8edf4a9f8e703c6350)