Those of you who have modded, or created content for the video game Half-Life (the original 1998 installment) know how picky its GoldSrc engine can get when it comes to file formats. Certain limitations must be strictly enforced lest you want to get a long list of errors. This extends to the images that will be used as world or model textures.

While there are several tools out there such as the veteran Wally or the Half-Life Texture Tools, they are mostly focused on creating and editing WAD files (archives that contain packages of textures). Sometimes you need something quicker and simpler, and that's why I wrote a small GIMP (free image editor) plug-in to do precisely that.

This plug-in (which is actually a Script-Fu script, written in GIMP's custom variant of the Scheme language) offers a straightforward interface to convert the currently opened image to proper GoldSrc format. It will also scale it down to 512x512 pixels (the maximum allowed texture size for models) or 256x256 (for world textures used in mapping) according to your choice. The resulting image will be saved to the same folder.

The script can be found in the Filters->Custom menu.

The plug-in interface is pretty simple.

Here you can download and check a sample texture, before and after conversion:

Original concrete texture suitable for floors or walls.

Download

Code

#!/usr/bin/env gimp-script-fu-interpreter-3.0

; Script-Fu script for GIMP 3 that exports the current image to valid GoldSrc
; (Half-Life 1) texture format. It resizes to 256x256 or 512x512 if needed,
; changes the precision to 8-bit integer, converts it to indexed mode with
; optimum palette generation, then exports it to BMP without writing color space
; information.

; Usage:
;     To install it, copy it to your GIMP scripts folder (see which one(s) in
;     Edit->Preferences->Folders->Scripts) and restart the program. Then, open
;     the image you want to export and run Filters->Custom->GoldSrc Export...


(define (script-fu-goldsrc-export image drawables size_small)
	; GIMP 3-only script.
	(script-fu-use-v3)

	(let* (
		; Compose the new BMP export filename from the original image. This
		; procedure will return %NULL if not loaded/imported/saved/exported yet.
		(old_filename (gimp-image-get-file image))
		(new_filename (if (or (equal? old_filename '()) (equal? old_filename ""))
			; A newly created image, unsaved. Append the extension to the name.
			(string-append (gimp-image-get-name image) ".bmp")
			; An existing image. Replace the file extension. NOTE: this will not
			; work with extensions different than 3 characters!
			(string-append (substring old_filename 0 (- (string-length old_filename) 4)) ".bmp")))
		(max_size (if (eq? size_small TRUE) 256 512)))

		; Resize the image if bigger than 256x256 (small) or 512x512 (large).
		(let* ((width (gimp-image-get-width image))
			   (height  (gimp-image-get-height image)))
			(when (or (> width max_size) (> height max_size))
				(let* ((scale_factor (min (/ max_size width) (/ max_size height))))
					(gimp-image-scale image (* scale_factor width) (* scale_factor height))
				)
			)
		)

		; Change precision to 8-bit integer (if not already so).
		(let* ((current_precision (gimp-image-get-precision image)))
			(when (not (= current_precision PRECISION-U8-NON-LINEAR))
				(gimp-image-convert-precision image PRECISION-U8-NON-LINEAR)
			)
		)

		; Convert image to indexed mode, generating optimum palette.
		(let* ((base_type (gimp-image-get-base-type image)))
			(when (not (= base_type INDEXED))
				(gimp-image-convert-indexed image CONVERT-DITHER-FS-LOWBLEED CONVERT-PALETTE-GENERATE 256 #t #t "")
			)
		)

		; Export as BMP, without writing color space information.
		(file-bmp-export RUN-NONINTERACTIVE image new_filename '() #f #f "rgb-888")
		(gimp-displays-flush)
	)
)


(script-fu-register-filter
	"script-fu-goldsrc-export"                                    ; Procedure name.
	"GoldSrc Export..."                                           ; Menu label.
	"Export image to valid GoldSrc (Half-Life 1) texture format." ; Description.
	"DaSalba"                                                     ; Author.
	"Copyright (c) 2025 DaSalba. MIT License."                    ; Copyright notice.
	"March 26, 2025"                                              ; Date created.
	"*"                                                           ; Image type that the script works on.
	SF-ONE-DRAWABLE                                               ; This plugin works with only one image/layer.
	SF-TOGGLE       "S_mall size (256x256)?" FALSE                ; Single parameter, if TRUE image will be max 256x256 instead of 512x512.
)

(script-fu-menu-register "script-fu-goldsrc-export" "<Image>/Filters/Custom")