Making a valid .smod from the command line

I am in the process of writing my first mod. I have a sample version of the mod working properly when the folder is placed into the mods folder. However, I cannot find a way to turn the file into a .smod via the command line that actually will load. I am using 7-zip, and I have tried different encryption methods, but none of them result in a file that Stonehearth will actually read.

My current (non-functional) code (in a .bat file):

rem Convert the file structure to a .smod file.
7z a -tzip item_value_mod.zip ".\Stonehearth Mod JSON Generator\files\out\item_value_mod\*"
del item_value_mod.smod
ren item_value_mod.zip item_value_mod.smod

???

Why don’t you just do it manually?

For what it’s worth, zipping with winRAR and renaming works like a charm!

2 Likes

if you have file extensions on (so you can see them) then you can turn your mod into a .Zip file, and rename the .Zip into .smod.

make sense?

2 Likes

I think that currently you zip your mod folder directly. Before, we had to select the manifest and the other files and send them to a zip folder, in order to make the mod load correctly as smod.

It must be something related to this.

3 Likes

Since this may not have been clear from the initial post, I want to make it clear that I want to have a command line option. I don’t want any solution that requires UI interaction (mouse click, context menus, etc.)

It’s complicated, but the short reason is because I’m using external (Java) code to write the mod, and I would like to be able to run a single batch file that runs my code (which generates all the files I need for the mod) AND creates the mod itself. Also, I hate using Windows UI for just about anything - I always prefer command line or keyboard shortcuts when possible.

I haven’t looked into winRAR, I will do so later today, thanks for the idea!

Yes, this makes sense. And if you look at the code I posted in the first post, I am already doing exactly that (line 2 creates the zip, line 3 deletes the old copy, and line 4 renames the zip to smod). Also, “file extensions on” doesn’t make sense in the context of command line / batch files. If you mean in the Windows UI, I NEVER, EVER have file extensions turned off. Having them turned off seems like a bad idea to me. Thanks for the idea and sanity check, though. Heaven knows I need more sanity checks. :stuck_out_tongue:

This is quite possible. Just so I understand, what do you mean, @Relyss, by “send them to a zip folder”? Do you send them to a new folder than zip it, or do you send them to a folder that’s already zipped (which, if possible, is new knowledge to me)?

You are correct that currently, I point 7-zip to a folder (item_value_mod) that contains both manifest.json and further subdirectories. For the mod to work, both the folder structure and file contents must be intact. My problem with the “copy files to another place, then zip that folder” is two-fold:

  1. I tried that earlier, and didn’t have any better results. (Note: It’s certainly possible that this is the best way to go, and I just wasn’t doing it correctly).
  2. I don’t know beforehand how many files (or even how many folders) will be created by my code, so the batch file command has to be a command that will work, recursively, for any number of files/directories.
2 Likes

I meant that there are two ways that you have to try. One of those has to work.
If I’m not mistaken, before we did this to package the mod (don’t mind the Spanish labels):

And currently we do it like this:

So you would have to copy the folder+contents, not only N files.

1 Like

The first way is how I’m attempting to do it via the command line (selecting all the contents of a folder, zipping it and all its folders’ content, then renaming it). As far as I can tell, the only end-result difference between these two would be whether all the content is inside a separate folder inside the mod (i.e., inside the mod, the manifest.json is located in crusader_mod/manifest.json) or not (the manifest would be in the root folder).

And that difference is enough to make a mod load or not :smile:

Lots of people had problems in the past with this, that’s why I tell you to try both methods…

3 Likes

Hmm, that’s interesting. You would think TR would specify which way needs to be done…

… and that fixed the problem. This is still doable from the command line, with 7zip used exactly as mentioned in the first post. I just created a new folder INSIDE item_value_mod folder and had my code write inside that new folder. Thanks, @Relyss, for the help. I don’t know why I missed such an obvious point, but I guess you live and learn.

Edit: And when your program makes a mistake and multiplies your intended item value by 1,000, you really have problems. Crafting one mean bed made me jump to over 4K net worth, triggering the goblins. Oops…

4 Likes

Okay, so a new problem, that you other modders might be able to help me with. I can create the .smod file locally, copy it into my mods folder, and it runs just fine. However, when I upload it to GitHub, download it, and run again, it fails to load. The log gives me the following error:

2015-Jul-16 18:27:28.004850 | server |  0 |                        resources | failed to load smod "item_value_mod": Illegal header in zip file
2015-Jul-16 18:27:28.005850 | server |  1 |                        resources | Modules have been modified by the user!

The file in question can be found here.

I changed a line in the manifest to not use uri in the mixintos but use the absolute path to the files being edited in the stonhearth.smod by your mod. also i made sure that the file structure was correct.

Download

This whole thread might be related to what we’ve discussed on GitHub already in Zulser’s issue #7:

Back then, .NET’s ZipArchive wasn’t good enough for Stonehearth for some reason. In your case, it might need some more parameters. You’re saying that the archive is zip, but not what kind of compression is used. I don’t know what SH can deal with, but I would guess it’s only the very vanilla zip thingy.

2 Likes

[quote=“Sral92x, post:11, topic:14631, full:false”]
I changed a line in the manifest to not use uri in the mixintos but use the absolute path to the files being edited in the stonhearth.smod by your mod. [/quote] Question: Why is using a URI a bad thing? And why is using absolute path better? I was able to make the mod work just fine with the URI on my box, I just couldn’t upload and re-download the file.

[quote=“Sral92x, post:11, topic:14631, full:false”]
also i made sure that the file structure was correct.[/quote] I downloaded your sample file, but it’s not helpful. When I try to unzip it (using either 7-zip or Windows’ built-in unzip), I get errors that prevent it from unzipping (Windows calls the file empty, 7-zip can’t open it as an archive).

I remember that conversation, and I was wondering if that was related to what I’m doing wrong now. The difference between this conversation and that one is that I am able to (locally) get a valid .smod file that the game recognizes and runs; I just can’t upload it to GitHub, re-download it, and get it to open again. It seems odd to me that I can run the local copy, but when I upload it, it somehow gains a magic Illegal header.

The archive I’m currently using is exactly as specified in the first post: I use 7-zip on the command line, using the -tzip formatting option. What settings in 7-zip have you used, @RepeatPan, to make your mods (that, as you mentioned in the link, we both agree work just fine)?

Do a binary diff of the files (original <-> GitHub issued). Maybe GitHub borks it - but that wouldn’t explain why I’m able to offer Zulser (and other mods) from GitHub just fine. I’m suspecting a faulty upload for some reason.

To zip it, I’m using the GUI with the shortcut (7zip -> Add to foo.zip). Not setting any options, that works fine.

[quote=“Xynariz, post:13, topic:14631, full:true”]

DId you rename it into a zip again or did you extract it just as is? I can just easily download and right click and tell 7zip to open it works that way for me

1 Like

Mind if I ask why you’re doing this? It sounds interesting, but why is it necessary? Do you have a large amount of similar items or something? I’m sure you have a good reason, I’m just curious. :smile:

1 Like

Well, it’s been a while since I posted to this thread. I hope to be able to code again today…

Well, now I feel stupid. While comparing the diff, I realized that they are a LOT different. The root issue is that I told it to download the HTML page about the file, rather than the file itself. It now works perfectly. Oops.

Once I do a release, I should be able to download the file in a single click (which I currently can’t do, I have to go to the file, then download the “raw” file).

[quote=“Sral92x, post:15, topic:14631, full:false”]
DId you rename it into a zip again or did you extract it just as is? I can just easily download and right click and tell 7zip to open it works that way for me
[/quote] I renamed it originally. You’re right, extracting as is works. I can see the change that you made in the manifest.json (stonehearth:furniture:not_much_of_a_bed to /stonehearth/entities/furniture/not_much_of_a_bed). However, I don’t understand how that makes any difference. Doesn’t stonehearth:furniture:not_much_of_a_bed already point there, since it’s aliased in the main stonehearth manifest.json (furniture:not_much_of_a_bed" : "file(entities/furniture/not_much_of_a_bed))? Also, you didn’t change my file structure at all, that I can see.

The root reason: I want to be able to make a (small) change to every file representing an item that is craftable from a recipe. It’s a lot easier to write a program that finds all those files dynamically then it is to write each one every time an item is added, changed, or removed.

2 Likes

i have the same problem on my mac. Its impossible to save the file as .smod file :frowning:

What im doing wrong?

You need to zip the folder, not its contents. In the way you are doing, you will have the files inside the zip, but what you need is to have the folder inside the zip, and inside that folder is the files, like this:

zip <- folder <- files
instead of
zip <- files

1 Like