Changelog

Version (dev)

  • Allow passing FrozenVec to VMF.make_prism()/make_hollow().

  • Fix bare strings on the end of CRLF lines eating the \r.

  • Escape characters like when exporting VMFs. This isn’t supported by regular Source, but can be added by mods.

Version 2.3.17

  • Added Keyvalues.serialise(), a replacement for export().

  • Fix + and = being parsed as part of a bare string if not the first character.

  • Fix keyvalue-type snippets causing a parse error for code coming after them.

  • Include filename/line number in missing snippet errors.

Version 2.3.16

  • Fix entity keyvalues being lowercased when parsed from files.

  • Add “snippets” to FGD parsing, allowing reuse of descriptions and other small pieces of data.

  • Allow VMTs to use /* */ comments.

  • #24: Fixed incorrect matrix.inverse() being calculated. PR by Ozxybox.

  • Allow omitting file/line number parameters for TokenSyntaxError.

  • Allow passing PrismFace to VMF.add_brush().

  • Parse Strata Source’s VMF displacement data.

  • Remove negative zeros when formatting vector and angle values.

  • Expand Angle/Matrix.from_basis() to pick the orientation if less than 2 vectors are provided.

  • Add vmf.Side.from_normal(), which generates a VMF face pointing in an arbitary direction.

  • Add vmf.Solid.point_inside(), which checks if a point is inside or outside a brush.

Version 2.3.15

  • HammerAddons#237: FGD model helpers should override each other.

  • Fix #20: VTF.compute_mipmaps() not working for cubemaps.

  • Correctly handle .vvd/.vtx etc files being packed as MODEL <srctools.packlist.FileType.GENERIC.

  • Improve performance of pure-Python VTF save/loading code.

  • Add Vec.clamped(), for applying min/max bounds to a vector.

  • Fix Entity.make_unique() renaming entities with numeric suffixes which were already unique.

Version 2.3.14

  • Drop support for Python 3.7.

  • Fix VMT parsing not handling Proxies { style braces.

  • Add Cythonised versions of conv_int(), :py:func`~srctools.conv_float` and :py:func`~srctools.conv_bool`.

  • Added a repr() for srctools.vmf.Entity.

  • Automatically clean up up empty sets when removing entities from VMF.by_class and .by_target.

  • Fixed saving/loading issues with a number of VTF formats.

Version 2.3.13

  • Renamed NO_FLASHLIGHT in bsp.StaticPropFlags to NO_SHADOW_DEPTH to reflect the actual behaviour of the flag, added the real NO_FLASHLIGHT define.

  • Add Tokenizer.preserve_comments, which produces COMMENT tokens instead of discarding them.

  • Fix #18: Incorrect module/function names in logging messages (via @ENDERZOMBI102).

  • Fix srctools.mdl.Model.apply_patches() not applying material proxies from the parent.

  • Use surrogateescape when eonciding/decoding BSP data, to allow values to round-trip.

Version 2.3.12

  • Handle the special $gender “variable” in WAV filenames.

  • Add prop_door_rotating class resource function.

  • Remove weapon_script class resource function, instead use a direct resource in the FGD.

  • Use typing_extensions.deprecated() to mark functions and methods which should not be used.

Version 2.3.11

  • Include the docs and tests in the source distribution.

  • Add support for detecting and packing weapon scripts.

  • Make custom model gibs inherit skinset when packing.

  • Add srctools.bsp.BModel.clear_physics(), to delete physics data for a brush model.

  • Add srctools.keyvalues.LeafKeyvalueError, raised when block-only operations are attempted on leaf keyvalues. This improves the messages raised and makes them consistent.

  • Fix srctools.vtf.Frame indexing behaviour. It would access totally incorrect pixels.

  • Correctly read/write L4D2’s BSP format.

Version 2.3.10

Version 2.3.9

  • Fix Cython version of Vec.join() using a default of x y z, not x, y, z.

  • Added support for the Chaos BSP format (by @ozxybox).

  • Improve internal FGD database format to allow parsing entities as they are required. For best efficiency, use EntityDef.engine_def() instead of FGD.engine_dbase() if possible.

  • Fix a few bugs with instance collapsing.

Version 2.3.8

  • Fix srctools.logger discarding trio.MultiError (or its backport) if it bubbles up to the toplevel.

  • Tweak VMF localise() and translate() type hints to allow FrozenVec as the origin.

  • Make movement and rotation of displacements work correctly.

  • Handle pitch keyvalues correctly when instancing, only rotating if it is a specific type.

  • Changed srctools.instancing.collapse_one() to use the entclass database directly, deprecating the fgd parameter as a result.

  • Fix BSP.surfedges incorrectly using edge 0, which may cause a single invisible triangle in maps.

Version 2.3.7

  • Removed some unusable constructor parameters from srctools.vmf.VMF, since they required passing in an object which requires the not-yet-constructed VMF as a parameter.

  • Renamed srctools.fgd.KeyValues to KVDef, so it is not confused with KV1 trees.

  • Replace on_error callback in srctools.logger.init_logging() with error, which now takes just an BaseException.

  • SurfaceProp has been rewritten to use attrs to simplify code.

  • Add srctools.run.send_engine_command(), which executes console commands in a running Source game.

  • Vec and FrozenVec no longer inherits from typing.SupportsRound, since typeshed updated the overloads for round() to permit zero-arg calls to return a non-int type.

  • Permit VMFs to accept frozen math classes directly as keyvalues.

  • Fix multiplying vectors and Vec.norm_mask() not producing FrozenVec.

  • Parse errors in BSP.ents are more informative and verbose.

  • Add an additional callback parameter to PackList.pack_into_zip() to finely control which files are packed.

  • Implement vector and angle stringification manually, to ensure .0 prefixes are always removed.

  • Use FrozenVec and FrozenAngle in the dmx module instead of namedtuple() subclasses.

  • Upgrade srctools.dmx.Time to a full class instead of a typing.NewType.

  • Fix packlist logic inadvertently discarding skinset keyvalue hints when packing models.

  • Change behaviour of DMX name and id attributes to match game logic. name is actually a regular attribute, but the uuid has a unique type and so can coexist with an attribute of the same name.

  • Add support for Black Mesa’s static prop format.

  • Support integer values for soundscript channels, instead of just CHAN_ constants.

  • Add a distinct exception (RootEscapeError) for when ../ paths go above the root of a filesystem.

Version 2.3.6

  • Add ability to specify resources used in entities to the FGD file, move internal class resource definitions to the Hammer Addons repository.

  • Added new srctools.fgd.EntityDef.get_resources() method, replacing fgd.entclass_*() methods.

  • When parsing VMF outputs, assume extraneous commas are part of the parameter.

  • Add FrozenVec, FrozenAngle and FrozenMatrix - immutable versions of the existing classes. This is a far better version of Vec_tuple, which is now deprecated.

  • Build Python 3.11 wheels.

  • Drop dependency on atomicwrites, it is no longer being maintained.

Version 2.3.5

  • Expand on documentation, build into explicit docs files.

  • Fix srctools.logging.LoggerAdapter.log() being invalid in Python 3.7.

  • Make srctools.fgd work when reloaded.

  • Remove blank srctools.choreo module.

  • Disable iterating on srctools.math.Matrix, this is not useful.

  • Add iterable parameter to srctools.dmx.Attribute.array(), for constructing arrays with values.

  • Fix DMX bool to float conversions mistakenly returning int instead.

  • Remove useless header_len attribute from srctools.vpk.VPK.

  • Rename srctools.property_parser.Property to srctools.keyvalues.Keyvalues, as well as NoKeyError and KeyValError.

  • Allow parsing srctools.fgd.IODef types which normally are not allowed for I/O. This will be substituted when exporting.

  • Use __class__.__name__ in reprs, to better support subclasses.

  • Issue #14: Disable some size checks on LZMA decompression, so more TF2 maps can be parsed.

Version 2.3.4

  • Add public submodules to __all__.

  • Disable escapes when parsing gameinfo files.

  • Add unprefixed vtx files to srctools.mdl.MDL_EXTS.

  • Skip empty folder/extension dicts when writing VPK files.

  • Clean up VPK fileinfo dicts when deleting files.

  • Default srctools.fgd.IODef to srctools.fgd.ValueTypes.VOID.

  • Sort tags when exporting FGDs, to make it determinstic.

Version 2.3.3

  • Writing out soundscript/particle cache can be non-atomic.

  • Vendor code from deprecated chunk.Chunk standard library class.

  • Fix bad use of builtin generics.

Version 2.3.2

  • Make particle systems use a cache file for the manifest too.

  • Make srctools.fgd.FGD.engine_db() actually cache and copy the database.

  • Automatically add the update folder to searchpath precedence, fixing TeamSpen210/HammerAddons#164.

  • Make DMX scalar type deduction more strict (removing iterable -> vec support), making it typesafe.

  • Add srctools.filesys.CACHE_KEY_INVALID.

  • Add srctools.math.Matrix.from_angstr().

Version 2.3.1

Version 2.3.0

  • Postcompiler code has been moved to HammerAddons.

  • Fix raw sound filenames not stripping special characters from the start when packing.

  • Allow srctools.dmx.Color to omit alpha when parsed from strings, and roound/clamp values.

  • Handle INFRA’s altered srctools.bsp.Primitive lump.

  • Read soundscripts and breakable chunk files with code page 1252.

  • Handle TF2’s LZMA compressed lumps.

  • Detect various alternate versions of srctools.bsp.StaticProp lumps, and parse them.

  • srctools.vmf.Entity now directly implements collections.abc.MutableMapping. Direct access to the Entity.keys dict is deprecated.

  • Correctly handle proxy blocks in VMT patch shaders.

  • DMX stub and null elements use an immutable subclass, instead of having elements be None-able.

  • Disallow entities to have a blank classname.

  • Elide long arrays in element reprs.

  • Add some additional logs when finding propcombine models fails.

  • Clean up srctools.Property.build() API.

  • Make error messages more clear when srctools.tokenizer.Tokenizer.error() is used directly with a Token.

  • Include potential variables in KeyError from srctools.vmf.EntityFixup.substitute().

  • Remove support for deprecated imghdr module.

  • Upgrade plugin finding logic to ensure each source is mounted under a persistent ID.

  • Add missing srctools.bsp.Primitive.dynamic_shadows.

  • Deprecate srctools.AtomicWriter, use the atomicwrites module.

  • srctools._class_resources is now only imported when required.

  • Use Cython when building, instead of including sources.

  • srctools.vmf.Entity.fixup will instantiate the EntityFixup object only when actually required.

Version 2.2.5

Version 2.2.4

  • Fix behaviour of Property.__getitem__() and Property.__setitem__().

  • Improve performance of VPK parsing.

  • Add support for Portal Revolution’s FGD helper tweaks.

  • Add option to collapse and remove IO proxies entirely.

  • Fix ModelCompiler creating directories with relative paths.

  • Pass through unknown model flag bits unchanged.

  • Fix VPK ascii check.

  • Handle VMF groups correctly.

  • Add srctools.math.Vec.bbox_intersect().

  • Allow indexing PrismFace objects by a normal to get a Side.

  • Add srctools.dmx.Attribute.iter_str() etc methods for iterating converted values. Directly iterating the Attribute is deprecated.

  • Add srctools.dmx.Attribute.append(), extend() and clear_array() methods.

  • Fix corruption from mistaken deduplication of srctools.bsp.VisLeaf and Primitive lumps.

Version 2.2.3

  • Fix use of builtin generics.

Version 2.2.2

  • Document some known particle manifest paths.

  • Handle double-spacing in animation particle options.

  • Improve type hints in srctools.smd.

Version 2.2.1

  • Missing particles is now an warning, not an error.

  • Particles are now case-insensitive.

  • py:meth:srctools.vmf.EntityFixup.keys(), values() and items() are now full mapping views.

  • Fix incompatibility with some Python versions.

Version 2.2.0

  • Make srctools.compiler.mdl_compiler generic, to allow typechecking results.

  • Add srctools.particles.

  • DMX attributes may now be copied using the copy module, and also tested for equality.

  • srctools.sndscript.Sound now lazily creates operator stack keyvalue objects.

  • srctools.packlist.Packlist now can pack particle systems, and generate particle manifests.

  • Animation events which spawn particles are also detected.

Version 2.1.0

  • Fix %-formatted logs breaking when srctools.logger is used.

  • Add Property.extend(), instead of using + or <Property.append() with a block. That usage is deprecated.

  • Deprecate creating root properties with name=None.

  • srctools.filesys.FileSystemChain is no longer generic, this is not useful.

  • Add functions which embed a Keyvalues1 tree in a DMX tree.