Absolute beginners guide to pk3s (draft)

Aside from the client itself, here is a list of:

EVERY file used in a game / how qc sends them to clients.
1. models (*.mdl) / precache_model()
2a. iqms (*iqm) / precache_model()
2b. the iqm’s image files (*tga, *.png, *.jpg) / precache_pic()
3. shaders (*.cfg) 
4. particle scripts (*.cfg)  /particleeffectnum()
5. images (*tga, *.png, *.jpg) /precache_pic()
6. glsl file (*.glsl)
7. maps (*.bsp)/ automacically downloaded when connecting
8. qwprogs.dat / not sent to client
9. csprogs.dat/ automacically downloaded when connecting
10. default.cfg
11. sounds (*.wav) / precache_sound()
12. charset / precache_pic()
13. skyboxes (image files)/precache_pic()
14. real time lighting files (*.rtlights)
15 *.lit files
16 *.lux files

By using precache_ functions, and making sure the files are on your server, clients will automatically download them. But not all files can be sent in this way. In the list above, all the items in green have to be manually downloaded by players (ie they go to a website, download, unzip into the correct directory). Normally this isn’t an issue, because these files can be included in the same zip which contains the client, and are automatically extracted into the right directory. But what if your game runs on a (dedicated) multiplayer server which regularly updates content? The answer is to stick the files in a pk3, and make the server send this pk3 to connecting players, and BOOM – they get the files – but how? Here’s what do to:

MAKING the pk3
1. make a new folder to represent your game’s root folder, lets call it ‘root2’

2. make subdirectories in root2, to imitate/match up with/mirror the directories in your mod folder, in which the files you need players to have are situated. eg, if the files you need to send are currently situated in


.. then root2 should contain those folders as well, eg:


3. Put a copy of all your required files in their corresponding directory in the root2 folder.



4. go into root2, select everything, and zip it, lets name the file ‘my_package’.

5. Change the extension from ‘zip’ to ‘pk3’, so the file is now called ‘my_package.pk3’

Note: just to be crystal clear, you selected everything IN root2, NOT root2 itself. ie the contents of my_package.pk3 are:


Note: there is no root2 folder in my_package.pk3

6. Use the following code (in world):

// put the name of the pack which contains THE_FILE into the string pak_name
string pak_name = whichpack(“scripts/foo.shader”, TRUE);

This references the file as if it were precached, and thus tells all clients to download my_package.pk3 (if they don’t already have it)

9. Upload my_package.pk3 to your server and put it in: Quake/modname

10. On your local computer, rename the files you copied to my_package.pk3, so your mod cant access them anymore. ie make sure ‘foo.shader’ does NOT exist on your server.  Note: All *.shader files are read, so changing ‘foo.shader’ to ‘fooxxx.shader’ wont work, because your mod will still read it, so change the extension, eg ‘foo.shaderxxx’. Rename all the files you copied to root2 in this way, so that the ONLY way your mod can load these files is from the pk3.

NOTE: During testing, you need to close and restart client to test if pk3s were opened or not; changing maps or vid_restart does NOT reload stuff from pk3s


Ok, lets say it’s been a week, and you want to edit a line in ‘foo.shader’, what do you do?

  1. Extract a copy of foo.shader into scripts/
  2. Now when you run your mod, it will use the local version, NOT the one still in my_package.pk3
  3. Edit it.
  4. Delete the old foo.shader in “root2/scripts”, and copy the new foo.shader there
  5. Rename it to foo2.shader
  6. Zip the contents of root2, and make a new pk3 called “my_package2.pk3”
  7. Upload my_package2.pk3 to your server, put it in Quake/modname
  8. whichpack(“scripts/foo2.shader”, TRUE); // update the name
  9. rename your local foo2.shader to stop it running: eg foo2.shaderxxx

Now the server will mark my_package2.pk3 as ‘referenced’ and players will download it.

Q: What if the pk3 is massive  – do players have to redownload it just because one line in one tiny file has changed?
A: If that’s the case, then don’t use this ‘regularly updated’ pk3 for big files(iqms, image files etc), make a special tiny pk3 which only has (tiny) scripts.

Leave a Reply




You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.