# Script to convert ZunTzu GameBox to VASSAL module

**URL:** <https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934>\
**Category:** News\
**Created:** [April 4, 2025, 7:03pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934 "2025-04-04T19:03:33Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 4, 2025, 7:03pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/1 "2025-04-04T19:03:33Z")

</div>

Hi all,

I’ve made a script that can convert a [ZunTzu](https://zuntzu.com) GameBox, including nested scenarios, to a VASSAL module. You can find it at

- [wargames\_tex / pywargame · GitLab](https://gitlab.com/wargames_tex/pywargame)

Use the script like

```shell
$ ztexport.py <ZTB file> [<OPTIONS>]

```

to generate a VASSAL module. Pass the option `--help` for help on options. For example the option `-p` which allows you to pass a Python script to patch the generated VASSAL module.

The generated module should be considered a _draft_, and you may need to flush things out in the VASSAL editor (or by other means).

The script is not omnipotent and your milage may vary 🙂

The script is part of the project [`pywargame`](https://gitlab.com/wargames_tex/pywargame) which also has a tool to [convert a CyberBoard scenario to a VASSAL module](https://forum.vassalengine.org/t/convert-cyberboard-scenario-to-vassal-module-as-esay-as-c-b-2-v/76095) as well as the Python module `vassal.py` to programmatically create and modify a VASSAL module.

You do not need to have `ZunTzu` or `VASSAL` installed to use these tools. All you need is Python.

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![KevOs4](https://forum.vassalengine.org/letter_avatar_proxy/v4/letter/k/e19adc/32.png) [@KevOs4](https://forum.vassalengine.org/u/KevOs4)\
**Post date:** [April 11, 2025, 1:51am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/2 "2025-04-11T01:51:16Z")

</div>

Christian -

Every attempt I have made to use this utility on my 64-bit Windows 10 system yields this sort of error:

I:\Documents\ZunTzu\>ztexport.py “Honour Alone v1.1c.ztb”  
Failed to build Honour Alone v1.1c.vmod: name ‘v’ is not defined  
Traceback (most recent call last):  
File “i:\documents\ZunTzu\ztexport.py”, line 12375, in   
raise e  
File “i:\documents\ZunTzu\ztexport.py”, line 12363, in   
exporter.run(output,patch)  
~~~~~~~~~~~~ ^^^^^^^^^^^^^^  
File “i:\documents\ZunTzu\ztexport.py”, line 10727, in run  
self.createBuildFile()  
~~~~~~~~~~~~~~~~~~~~ ^^  
File “i:\documents\ZunTzu\ztexport.py”, line 11620, in createBuildFile  
self.addScenarios()  
~~~~~~~~~~~~~~~~~ ^^  
File “i:\documents\ZunTzu\ztexport.py”, line 12154, in addScenarios  
self.addScenario(sc,menu)  
~~~~~~~~~~~~~~~~ ^^^^^^^^^  
File “i:\documents\ZunTzu\ztexport.py”, line 12190, in addScenario  
piece\_map = self.remapIds(scenario)#self.\_gamebox.\_piece\_map  
File “i:\documents\ZunTzu\ztexport.py”, line 12164, in remapIds  
v(f’Missing counter sheet {layout.\_name} - maybe map’)  
^  
NameError: name ‘v’ is not defined

Any suggestions? Thanks.

---

<div class="post-metadata">

**Author:** ![alecrespi](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/alecrespi/32/7154_2.png) [@alecrespi](https://forum.vassalengine.org/u/alecrespi)\
**Post date:** [April 11, 2025, 6:33am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/3 "2025-04-11T06:33:38Z")

</div>

Hi,  
try renaming the original file (Honour Alone v1.1c.ztb) to something simpler (like HA11.ztb) and see if it gives the same error message…

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 11, 2025, 6:47am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/4 "2025-04-11T06:47:54Z")

</div>

> [@KevOs4](#):
>
> File “i:\documents\ZunTzu\ztexport.py”, line 12164, in remapIds  
> v(f’Missing counter sheet {layout.\_name} - maybe map’)  
> ^  
> NameError: name ‘v’ is not defined

A bug had snug in when fixing another bug 🙂 Try redownloading the script.

> [@alecrespi](#):
>
> try renaming the original file (Honour Alone v1.1c.ztb) to something simpler (like HA11.ztb) and see if it gives the same error message…

While spaces in file names are sometimes problematic - @KevOs4 did correctly quote the file name - that was not the issue. It was a mistake on my part 🙂

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 11, 2025, 7:06am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/5 "2025-04-11T07:06:42Z")

</div>

> [@KevOs4](#):
>
> File “i:\documents\ZunTzu\ztexport.py”, line 12164, in remapIds  
> v(f’Missing counter sheet {layout.\_name} - maybe map’)  
> ^  
> NameError: name ‘v’ is not defined

BTW, consider to put logs, errors, etc. in between a set of triple back-tics ````` like

````
```
File “i:\documents\ZunTzu\ztexport.py”, line 12164, in remapIds
v(f’Missing counter sheet {layout._name} - maybe map’)
^
NameError: name ‘v’ is not defined
```

````

That makes the error messages far easier to read and makes it easier for anyone to help you. Thanks.

**N.B.** : The Forum platform allows for use of [MarkDown](https://en.wikipedia.org/wiki/Markdown), which can give your posts rich formatting and really make them stand-out and easier to read.  
**Bold** face is done by putting two `*` around the thing to put in bold face as in ` **Bold** `.  
_Italics_ can be done with two `_`, as in `_Italics_`.

Links are `[Link text](link url)` - e.g., `[VASSAL](https://vassalengine.org)`.

Images can be included with `![Alternate text](image url)` - for example `[VASSAL banner](https://vassalengine.org/images/wordmark-path.svg)`.

Tables are also possible with `|` and `-`, as

```auto
| Column 1 header | Column 2 header |
|-----------------|-----------------|
| Row 1 column 1 | Row 1 column 2 |
| Row 2 column 1 | Row 2 column 2 |

```

to give (note - spaces are largely irrelevant)

| Column 1 header | Column 2 header |
| --- | --- |
| Row 1 column 1 | Row 1 column 2 |
| Row 2 column 1 | Row 2 column 2 |

Lists are easily done with a `-` or `*` at the start of the line, and they can be nested by putting 2 spaces in front of subsequent `-` or `*`

```auto
- First item
- Second item
  - 1st sub item of second item 
  - 2nd sub item of second item
- 3rd item

```

to give

- First item
- Second item
  - 1st sub item of second item
  - 2nd sub item of second item

- 3rd itemd

Numbered lists are similar, except they start with _some_ number followed by a period `.`, e.g., and sub items are indented by 3 spaces

```auto
1. foo
   1. bar 
   4. baz 
5. Gnus
2. Gnat

```

yielding

1. foo
  1. bar
  2. baz

2. Gnus
3. Gnat

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![KevOs4](https://forum.vassalengine.org/letter_avatar_proxy/v4/letter/k/e19adc/32.png) [@KevOs4](https://forum.vassalengine.org/u/KevOs4)\
**Post date:** [April 11, 2025, 5:32pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/6 "2025-04-11T17:32:55Z")

</div>

Christian -

Yes, that fixed the problem. The conversion works remarkably well now, although the results are (as you admit) not perfect. Thank you.

TG

---

<div class="post-metadata">

**Author:** ![KevOs4](https://forum.vassalengine.org/letter_avatar_proxy/v4/letter/k/e19adc/32.png) [@KevOs4](https://forum.vassalengine.org/u/KevOs4)\
**Post date:** [April 11, 2025, 6:35pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/7 "2025-04-11T18:35:28Z")

</div>

Christian -

I suggest that you convert counters to have twelve steps of rotation rather than six in order to match the ZT standard.

TG

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 11, 2025, 7:03pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/8 "2025-04-11T19:03:18Z")

</div>

> [@KevOs4](#):
>
> although the results are (as you admit) not perfect.

Do remember to play with the various options for the script - in particular the `-a` option. The default is to assume that boards are alternative boards. That’s true in some cases, and not in others - depending on how the developer made the Zun Tzu game box (the distinction is a little clear in VASSAL). Hence, for some game boxes it makes sense with the default and for others it make sense to use the `-a`. There’s no way, as far as I can tell, to figure the right setting form the Zun Tzu game box itself.

> [@KevOs4](#):
>
> I suggest that you convert counters to have twelve steps of rotation rather than six in order to match the ZT standard.

I was considering that too. ZunTzu seems to allows an almost infinite number of rotations, which _is_ possible in VASSAL, but is often not the right thing.

Also, the ZunTzu save format allows one to specify a rotation and a front-back flip state. That is also possible in VASSAL, but because of the rather obscure save format of VASSAL, it is a bit of a head-ache to implement.

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 11, 2025, 10:20pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/9 "2025-04-11T22:20:00Z")

</div>

Hi all,

I’ve updated the script a bit more, and fixed some rather annoying bugs that meant the script got a lot of stuff wrong much of the time. Should be OK now. Also, the flipped and rotated states of pieces is now propagated to the generated save files. Should make life a little easier.

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![KevOs4](https://forum.vassalengine.org/letter_avatar_proxy/v4/letter/k/e19adc/32.png) [@KevOs4](https://forum.vassalengine.org/u/KevOs4)\
**Post date:** [April 12, 2025, 1:16am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/10 "2025-04-12T01:16:32Z")

</div>

Christian -

Thanks for this work. Converted scenarios now show rotation, but, unfortunately, it is not the correct rotation. Here’s an example:

 ![Rotation](https://forum.vassalengine.org/uploads/default/original/2X/1/1e6b60a0c20b07f8717b4f0ce9e652451b4884c1.jpeg)

I think this could be at least partly due to the 6 steps vs. 12 steps issue. The gamebox in question is _Atlanta Campaign_.

By the way, I have never encountered a ZTB that had anything other than 12 steps of rotation.

TG

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 12, 2025, 2:11am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/11 "2025-04-12T02:11:58Z")

</div>

> [@KevOs4](#):
>
> I think this could be at least partly due to the 6 steps vs. 12 steps issue

You can set the number or rotation steps with the option `-R`. If you set it to `1` you will get infinite rotations.

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![KevOs4](https://forum.vassalengine.org/letter_avatar_proxy/v4/letter/k/e19adc/32.png) [@KevOs4](https://forum.vassalengine.org/u/KevOs4)\
**Post date:** [April 12, 2025, 3:41am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/12 "2025-04-12T03:41:21Z")

</div>

Christian -

My guess was wrong. Adding the switch -R12 does indeed change the setup, but now all rotated pieces have exactly the same orientation in the Vassal module regardless of their original facing in the ZunTzu gamebox:

 ![rotation2](https://forum.vassalengine.org/uploads/default/original/2X/9/90eb113dc6ca1ed1f8eb39fba7c9f66f729db02a.jpeg)

But, at least now it is possible to correct the rotations manually, which previously required an initial edit of the Basic prototype in the VMOD.

I really do appreciate your diligence in addressing this issue.

TG

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 12, 2025, 7:12am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/13 "2025-04-12T07:12:35Z")

</div>

> [@KevOs4](#):
>
> The gamebox in question is _Atlanta Campaign_.

Could you provide a link? That really would help in finding any possible bugs, as it is difficult to test against all possible variantions of game boxes.

> [@KevOs4](#):
>
> Adding the switch -R12 does indeed change the setu

There should be a space between `-R` and `12` as in

```auto
./ztexport.py -R 12 AtlantaCampaign.ztb ... 

```

Otherwise, it may be interpreted incorrectly. which may be the reason for

> [@KevOs4](#):
>
> ow all rotated pieces have exactly the same orientation

> [@KevOs4](#):
>
> I really do appreciate your diligence in addressing this issue.

No worries. But I would still like test against your game box, so please provide a link. Thanks.

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 12, 2025, 8:58am UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/14 "2025-04-12T08:58:34Z")

</div>

> [@KevOs4](#):
>
> now all rotated pieces have exactly the same orientation

OK, I think I found the problem - VASSAL has a very funny way of calculating rotation index when using a fixed number of rotations.

> [@KevOs4](#):
>
> By the way, I have never encountered a ZTB that had anything other than 12 steps of rotation.

ZunTzu as such does not define a way to specify the number of rotation steps. Instead, it seems to allow for arbitrary rotations (or at least a great many number of them), so it would seem wrong to say they _always_ allow 12 rotations - ZunTzu has no concept of limiting rotations at all. If you pass `-R 1` you will get more or less the same behaviour in the generated VASSAL module.

Still, I’d like to test things on the game box you are playing with - please provide a link.

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![KevOs4](https://forum.vassalengine.org/letter_avatar_proxy/v4/letter/k/e19adc/32.png) [@KevOs4](https://forum.vassalengine.org/u/KevOs4)\
**Post date:** [April 12, 2025, 4:05pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/16 "2025-04-12T16:05:48Z")

</div>

Christian -

I did not post this particular gamebox to the ZunTzu website due to intellectual property concerns, but you can use [Iron Brigade](https://zuntzu.com/files.htm#I) for testing instead, as a conversion appears to exhibit the same behavior.

TG

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 13, 2025, 12:11pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/17 "2025-04-13T12:11:06Z")

</div>

> [@KevOs4](#):
>
> I did not post this particular gamebox to the ZunTzu website due to intellectual property concerns,

Not sure exactly what you mean by “Intellectual Property” - Copyright? Trademark? …?

> [@KevOs4](#):
>
> but you can use [Iron Brigade](https://zuntzu.com/files.htm#I) for testing instead, as a conversion appears to exhibit the same behavior.

Well, the [Iron Brigade](https://zuntzu.com/files.htm#I) game box saves do not really rotate pieces beyond the 60° intervals, so in that sense, it’s not a good test.

Also, I looked through the [source code of ZunTzu](https://github.com/ZunTzu-Software/ZunTzu) and it seems that ZunTzu does rotations in increments of 10° _always_. In that sense, a reasonable default would be `-R 36`.

Anycase, try re-downloading `ztexport.py` - I’ve fixed a number of things, and also add symbolic dice - similar to ZunTzu’s (though not animated).

Yours,  
_Christian_

---

<div class="post-metadata">

**Author:** ![KevOs4](https://forum.vassalengine.org/letter_avatar_proxy/v4/letter/k/e19adc/32.png) [@KevOs4](https://forum.vassalengine.org/u/KevOs4)\
**Post date:** [April 13, 2025, 4:20pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/18 "2025-04-13T16:20:38Z")

</div>

Christian -

I should clarify. Facing changes are so quick and easy in ZunTzu that there is no need to limit the degree of change. In contract, with Vassal it is best to optimize the number of rotations in order to avoid the need for repeated keypresses. But, twelve steps are desirable in the conversions so that the output can handle any combination of facing type (hexside or hexpoint) and grain (vertical or horizontal).

“Intellectual property” is the collective legalese term covering patent, trademark, and copyright.

TG

---

<div class="post-metadata">

**Author:** ![cholmcc](https://forum.vassalengine.org/user_avatar/forum.vassalengine.org/cholmcc/32/8319_2.png) [@cholmcc](https://forum.vassalengine.org/u/cholmcc)\
**Post date:** [April 13, 2025, 8:25pm UTC](https://forum.vassalengine.org/t/script-to-convert-zuntzu-gamebox-to-vassal-module/84934/19 "2025-04-13T20:25:31Z")

</div>

> [@KevOs4](#):
>
> I should clarify. Facing changes are so quick and easy in ZunTzu that there is no need to limit the degree of change. In contract, with Vassal it is best to optimize the number of rotations in order to avoid the need for repeated keypresses. But, twelve steps are desirable in the conversions so that the output can handle any combination of facing type (hexside or hexpoint) and grain (vertical or horizontal).

If you choose free rotation, `-R 1` with `ztexport.py`, you have a similar behaviour to ZunTzu: Select piece or stack, press short cut or select from context menu, and drag to rotate. Not a question of key strokes, but of meaningful rotations relative to the game. For most hex’n’counter 6 facings is all you want, if at all ZunTzu does not have those considerations and applies a one-rule-fits-all approach.

You can of course choose whatever number of facings, including “infinite” , that best fit your needs.

> [@KevOs4](#):
>
> “Intellectual property” is the collective legalese term covering patent, trademark, and copyright.

“Intellectual property” has no well-defined legal meaning, and is mostly used by cooperate people to refer to some vague, ill defined concept. Historically, “Intellectual property” has been used to scare competitors without much substance. In terms of games, I generally refer to [this thread](https://boardgamegeek.com/thread/493249/) on BGG, which lays out the legal terms quite well.

I hope the recent changes to `ztexport.py` works for you and you can get a good starting point for further VASSAL developments.

Yours,  
_Christian_
