bsp_tool icon indicating copy to clipboard operation
bsp_tool copied to clipboard

save_as() method for every BspClass

Open snake-biscuits opened this issue 4 years ago • 10 comments

Any changes made to a .bsp should be saved back to that .bsp by bsp_tool The user shouldn't have to worry about specifics like lump containing offsets However confirming the saved map is valid will not be a feature at this time (could use an optional branch script method as a fuzzy validator for engine limit checks etc.)

NOTE: this means Quake / GoldSrc lumps like MIP_TEXTURES need to be handled with SpecialLumpClasses or maybe even a new class in the lumps module

TRACKER: base.Bsp subclasses with a functional & tested .save_as() method

  • [ ] IdTechBsp
    • [ ] Genesis3DBsp
    • [ ] InfinityWardBsp
      • [ ] D3DBsp
    • [ ] RavenBsp
    • [ ] RitualBsp
  • [ ] QuakeBsp
    • [ ] GoldSrcBsp
    • [ ] ReMakeQuakeBsp
      • [ ] Quake64Bsp
  • [x] ValveBsp
    • [x] RespawnBsp

Further TODOS

  • [ ] #109
  • [x] tests/test_save.py needs to be content aware, otherwise saves must be byte-for-byte

snake-biscuits avatar Aug 19 '21 15:08 snake-biscuits

~~Titanfall2 / Apex Legends .save_as doesn’t respect external lumps, see #12 for more~~

snake-biscuits avatar Dec 20 '21 20:12 snake-biscuits

Titanfall2 / Apex Legends .save_as doesn’t respect external lumps, see #12 for more

This has been addressed now, but we do need automated testing to ensure this remains stable.

All an automated test needs to confirm (for now) is that loading and saving a .bsp matches the source file byte-for-byte

snake-biscuits avatar Feb 05 '22 22:02 snake-biscuits

All base.Bsp subclasses with their unique _preload methods will need their own implementation of the save_as method Inheritance should cover any .bsp this doesn't apply to (e.g. GoldSrcBsp inherits _preload from QuakeBsp)

snake-biscuits avatar Feb 05 '22 22:02 snake-biscuits

All base.Bsp subclasses with their unique _preload methods will need their own implementation of the save_as method

The top comment tracks each base.Bsp subclass this applies to, but their subclasses should also be tested to be sure For ensuring save_as remains stable we will need enough maps for each branch_script to test the contents of every lump Any edge cases that arise in SpecialLumpClasses etc. will also need to be permanently tracked with a map & test for that issue

During the initial development of each .save_as method we should also confirm each map against at least 1 game (test it runs) Occasionally doing this with test maps going forward would also be useful. Keeping a mental image of how the map should function will hopefully limit "coding in the dark"

snake-biscuits avatar Apr 22 '22 13:04 snake-biscuits

Automated testing for .as_bytes() methods will be a big help here Probably something to implement in branch script testing

snake-biscuits avatar Jun 18 '23 04:06 snake-biscuits

#112 shows that we need to test all .as_bytes() methods, specifically for SpecialLumpClasses Explicitly! Not just indirect testing through .save_as()

Building tests to support .save_as() is bringing out the deep code coverage Which is great because it means assumptions are getting drawn out & confronted

snake-biscuits avatar Jul 02 '23 06:07 snake-biscuits

tests/test_save.py needs to be content aware, otherwise saves must be byte-for-byte

refactors to extensions.diff should now cover this still need some specialised classes for diffing SpecialLumpClasses but the refactor has standardised how to do that and is much more modular now

snake-biscuits avatar Jul 21 '23 05:07 snake-biscuits

#143 found some bugs w/ RespawnBsp.save_as() Going to open a new Issue for testing all RespawnBsp's cases in a bit

snake-biscuits avatar Aug 24 '23 21:08 snake-biscuits

IdTechBsp (& by extensions QbismBsp) should include BSPX data All BspClasses should be appending their ._tail(), but BSPX is padded

We might need to categorise other tails to see if they need padding too

>>> import bsp_tool, os, fnmatch
>>> md = "E:/Mod/QuakeII/rerelease/pak0/maps/"
>>> maps = {m[:-4]: bsp_tool.load_bsp(os.path.join(md, m)) for m in fnmatch.filter(os.listdir(md), "*.bsp")}
>>> subfolders = {d for d in os.listdir(md) if os.path.isdir(os.path.join(md, d))}
>>> maps.update({
...     f"{sd}/{m}"[:-4]: bsp_tool.load_bsp(os.path.join(md, sd, m))
...     for sd in subfolders
...     for m in fnmatch.filter(os.listdir(os.path.join(md, sd)), "*.bsp")})
... 
>>> bspx_maps = {m: b for m, b in maps.items() if b"BSPX" in b._tail()}
>>> {b.__class__ for b in bspx_maps.values()}
{bsp_tool.id_software.IdTechBsp, bsp_tool.id_software.QbismBsp}

Related

  • #188

snake-biscuits avatar Jun 14 '24 04:06 snake-biscuits