Newbie Modder's Tutorial (Part 1)

Users who are viewing this thread

fisheye

Not valid for 0.731 or later.

Newbie Modder’s Tutorial

Source code for Horse Merchant minimod here:
http://www.mbrepository.com/modules/PDdownloads/visit.php?cid=4&lid=77

* Thanks to Khalid for his excellent City tutorial: http://forums.taleworlds.com/viewtopic.php?t=5744

* Thanks to Janus for publishing his Arena Mod source code.

Part 1: Creating a new map location

Lesson Goal:
Creating a new visitable map location

In this lesson we’ll be starting a new module called “Horse Merchant”.

Starting Out

First, we’ll need a copy of the native module to modify.
Copy the folder Mount&Blade\Modules\Native to Mount&Blade\Modules\HorseMerchant

This will create a new module, called HorseMerchant, that is identical to the native module in all respects. You can run this module from the M&B launch screen just like any other module. Right now it’s quite pointless since it’s just like the native module, but later we’ll be performing some edits on it.

Now download the official editor. Instructions here:
http://forums.taleworlds.com/viewtopic.php?t=5408

The “official editor” is somewhat of a misnomer, since it’s not really an editor, but is actually a bunch of python scripts that generate the machine-readable codes in the .txt files of the actual module. You can think of it as the “source code” of your new module. What you’re downloading is actually a copy of the source code of the Native module. Hence, make a copy of it in your module directory. Call it “source” or something suitably descriptive.

Note that the source code is in a very limited “Mount and Blade” language, NOT Python. In fact, you don’t need to know any Python to program a sophisticated mod. In fact you don’t even need to know how to program at all, as long as you have a reasonable understanding of the M&B operators you will be using (which have nothing to do with Python).

Starting the Scene

Now start Mount and Blade up in Edit mode (set it in the configurations). For details about edit mode, see:

http://forums.taleworlds.com/viewtopic.php?t=5623

Have fun and play with it a bit. Press H for help. Don’t save anything!

Now go to the overland map and look for the new “terrain” button in the lower left corner. Play with the settings until you have a nice flat plain. Putting “1” in the tree seed tends to remove a lot of the trees. Now copy the terrain code (circled in red on the screen shot below) onto a piece of paper.

l01-ss002-s.jpg


Open HorseMerchant/source/module_info.py and change the directory to the correct one, e.g.

export_dir = "C:/Program Files/Mount&Blade/Modules/HorseMerchant/"

Now we’re going to make some changes. First, let’s start by making a copy of an existing scene. The Four Ways Inn will do. Copy:

HorseMerchant/SceneObj/scn_four_ways_inn.sco
to
HorseMerchant/SceneObj/scn_horse_emporium.sco

To add this file to the list of scenes accessible from our module, go to your HorseMerchant/source folder. Open module_scenes.py and find the entry associated with the Four Ways Inn. Copy and paste the line to the bottom of the file, just before the last close brace, and change the identifier name “four_ways_inn” to our new identifier “horse_emporium”. Replace the long sequence of numbers at the end of the line with your own long sequence of numbers that you copied off the terrain generator. You should now have something like this at the end of your module_scenes.py:

Code:
  ("rivacheg_smithy",sf_indoors, "thirsty_lion", "bo_thirsty_lion", (-100,-100),(100,100),-100,"0",
    ["exit"],[]),
  ("rivacheg_merchant",sf_indoors, "thirsty_lion", "bo_thirsty_lion", (-100,-100),(100,100),-100,"0",
    ["exit"],[]),

  ("horse_emporium",sf_generate,"none", "none", (0,0), (120,120), -100,"0x324099f400025896000000010000705c00003693",[],[]),

]

Explanation of the fields: “horse_emporium” is the name of the scene. It will read the scene object file “scn_horse_emporium.sco” in the SceneObj directory. If we had called it “khergit_lavatory”, M&B would look for the file “scn_khergit_lavatory.sco” in the scene directory. “sf_generate” means that the terrain is dynamically generated each time this scene is entered, based on the terrain parameter, “0x324099f400025896000000010000705c00003693”. Other scene flags can be found in header_scene.py.

All the other fields are irrelevant to dynamically generated scenes since they are automatically set by the terrain generator; I describe them for completeness, but you can just skip to the next paragraph. The next two fields (“none”,”none”) indicate the display mesh and collision mesh of the scene respectively. Since our scene is dynamically generated in one big terrain package-deal, we don’t need to specify these; hence they are “none” and “none”. If we had the sf_indoors flag set (e.g. in the rivacheg_merchant scene right above it), then we’d need to tell the program how to display the walls, floors, etc, and also which objects are passable or impassible. The next two parameters indicate the bounds of the area; in this case the “southwest” corner is (0,0) and the northwest corner is (120,120). Finally the parameter after that is the water table; any terrain lower than that will be “underwater”, i.e. a riverbed or the bottom of a pond. The second-last parameter [] is deprecated; ignore it. The final parameter is a list of chest troops for the scene. For example the Zendar tavern lists the zendar chest here. A chest troop is just a troop that consists of nothing but an inventory. We'll learn how to make chests in a later lesson.

Locating the Scene on the Overland Map

In the next step we need to figure out where to place this new location.

Install and run Thorgrim’s map editor:
http://forums.taleworlds.com/viewtopic.php?t=5646

l01-ss003-s.jpg


This is an amazing tool that can let you create any landscape you wish, but for now we’re just using it to choose a new location for the horse merchant. Got to Menu (lower-right corner), Load, and select HorseMerchant. Now click the “add location” button (looks like a little castle) and click once on the “+” button that just appeared. Mouse over the map, click once. A little city will appear with a name like “Town 45” (doesn’t matter exactly what, could be Town 99 if you clicked that + a lot, but that’s ok). Move it into the place you want by clicking and dragging. Don’t bother renaming the town at this point. Save. Don’t worry about any warnings that pop up at this point.

Install and run Effidian’s Unofficial Editor:
http://forums.taleworlds.com/viewtopic.php?t=5937

This amazing tool would have allowed us to create this mod without touching any of the python files, but a good modder needs to know how to use both. Now File-Open your HorseMerchant module. You’ll see a map of Calradia displayed on screen. Go to View->Parties. Find p_town_45 (or p_town_46 or whatever your number was on the map editor). Write down the X and Y positions of your town. In this example they are (8.36, 43.25). Quit without saving.

Making the Scene Active

Now we are ready to add this scene onto the source code. Open module_parties.py. “Parties” is also a bit of a misnomer since it refers to both overland or static armies (like the garrisons you can hire in the Taverns) as well as anything that can appear on the overland map; cities (e.g. Rivacheg), locations (e.g. Dhorak Keep) and spawn points (e.g. River Pirate Spawn Point).

Now look for the “four_ways_inn” party, copy the line to the space below. Modify “four_ways_inn” to “horse_emporium” (twice), and “Four_Ways_Inn” to “Horse_Emporium”. Also, change the coordinates (4.8, -19.6) to the coordinates we recorded in the previous step (e.g., (8.36,43.25)). You should get:

Code:
("four_ways_inn","Four_Ways_Inn",icon_town|pf_is_static|pf_always_visible, "four_ways_inn", pt_none, fac_neutral,0,ai_bhvr_hold,0,(4.8, -19.6),[(trp_swadian_knight,6,0)]),
  ("dhorak_keep","Dhorak_Keep",icon_town|pf_is_static|pf_always_visible, "dhorak_keep", pt_none, fac_neutral,0,ai_bhvr_hold,0,(-50,-58),[(trp_swadian_knight,6,0)]),
  ("horse_emporium","Horse_Emporium",icon_town|pf_is_static|pf_always_visible, "horse_emporium", pt_none, fac_neutral,0,ai_bhvr_hold,0,(8.36, 43.25),[(trp_swadian_knight,6,0)]),

Description of arguments:
* “horse_emporium”: party id, when referring to this party we use the string “p_horse_emporium”
* “Horse_Emporium”: party name, this is the string that is displayed on the overland map.
* icon_town|pf_is_static|pf_always_visible: party flags. In this case, this means display this party with the town icon, this party is static (i.e. a location), and it’s always visible (e.g. it can be seen from all the way across the map without any spotting skill). Other flags are in header_parties.py; you can guess their meaning by how they are used in other parties.
* “horse_emporium”: this is the name of the menu that is executed when the party is encountered. We’ll be creating this next.
* pt_none: this is the name of the party template that the party belongs to. It seems unused right now, every party has pt_none in this field.
* fac_neutral: this is the faction of the party; in this case, the horse merchant is a Neutral party. You could, for example, set it to fac_swadians or fac_vaegirs.
* 0 : personality, describes how aggressive/courageous the party is on the overland map. High aggressive parties will actively seek out enemies to attack, low courageous parties will flee from larger parties. Since a location is immobile, this field is irrelevant here, hence 0.
* ai_bhvr_hold: AI behavior. In this case, this behavior says “stay right here”. Other behaviors do other things, e.g. ai_bhvr_travel_to_point causes the party to go towards a designated point.
* 0 : AI target, used to specify whom/where the AI behavior is going to.
* (8.36,43.25): Overland map coordinates of the party. This is where we entered the map coordinates that we recorded in the previous step.
* [(trp_swadian_knight,6,0)] : list of troops in the party. This is actually irrelevant in a location so we’ll just leave whatever we copied. We’ll learn how to use this field in a later lesson.

Scene Menus

We’ll need a game menu to take care of what happens when the player reaches and clicks on this map location. Open module_game_menus.py and copy-and-paste the salt mine game menu to make a new entry just below it. Change it to the following:

Code:
  (
    "salt_mine",mnf_auto_enter,
    "You enter the salt mine.",
    "none",
    [[reset_price_rates],[set_price_rate_for_item,"itm_salt",55]],
    [
      ("enter",[],"Enter.",[[set_jump_mission,"mt_visit_town_horseback"],[jump_to_scene,"scn_salt_mine"],[change_screen_mission]]),
      ("leave",[],"Leave.",[[leave_encounter],[change_screen_return]]),
    ]
  ),
  (
    "horse_emporium",mnf_auto_enter,
    "You enter Honest Hamid's Horse Emporium.",
    "none",
    [[reset_price_rates]],
    [
      ("enter",[],"Enter.",[[set_jump_mission,"mt_town_default"],[jump_to_scene,"scn_horse_emporium"],[change_screen_mission]]),
      ("leave",[],"Leave.",[[leave_encounter],[change_screen_return]]),
    ]
  ),

The fields are explained in the comments at the top of the file, so I’ll just explain how I modified them.

* “horse emporium”: name of the menu, this identifies it as the menu that is called when the party described in the previous section is clicked.

* mnf_auto_enter: the party automatically enters the location without waiting for user response.

* Reset_price_rates: this clears any funky prices that were left over from visiting a previous city (e.g. if you just came from Zendar, salt will be pricey and tools will be cheap – this sets it back to the baseline prices).

* “enter”… : this is the enter option on the menu, automatically selected due to the mnf_auto_enter flag. It has no preconditions [], would have been displayed as a button “Enter” if not for auto-entry, and next is a list of commands to fire up the mission for exploring the scene itself. There are three commands here, in the format [ [first command], [second command], [third command] ]. In general you can have as many commands as you like. First we choose the mission template for town exploration “mt_town_default”, then we change the active scene to our new scene “scn_horse_emporium”, and then finally we actually perform the switch from the overland view to the mission view.

* “leave”…: this option is never actually used thanks to mnf_auto_enter, so we’re just leaving it as the default leaving option. The commands in leave are not hard to understand: we just leave the menu system (leave_encounter) and go back to the view that we were in, in this case the overland map (change_screen_return).

Finally we are done with editing the source code!

Run build_module.bat to compile your scripts. If you didn’t make any typos, it should compile fine.

Setting the Scene, placing placeables

Now fire up M&B in edit mode in your new module. Create a new character, leave Zendar, and you should see the Horse Emporium nearby.

l01-ss004-s.jpg


Go to it, and it will put you into a scene that looks exactly like the Four Ways Inn with somewhat different terrain.

Now you can press Ctrl-E to edit the scene into whatever you like! Remember that you always need Entry Point 0 to denote where the player will start out. Also, place an Entry Point 1 to reserve a spot for where Hamid will appear later. When you’re done, press Ctrl-E again and the scene will be saved. Voila! You are now the proud owner of a new map location.

l01-ss005-s.jpg


Up next: Lesson 2: Making a new character.
 
Very nice!

Please put the link to this thread in
http://www.thorned.nl/oninran/viewforum.php?f=22
 
Very nice Fisheye ( I could have used this about a week ago - LOL - had to figure all of this out on my own).

Thanks for taking the time to document it!! I am sure it will help many who follow.

DE
 
Yeah, very good and detailed tutorial. I know it will be useful for many people interested in working on mods.
One tiny thing to correct: you refer to the copied scene as the Four Ways Inn at one point and the Salt Mine in another. :wink:
 
I can't get it to compile my scripts. What's up? It says that it can't find *.pyc.

EDIT: I found a solution, but it wasn't the batch file. I still don't know how to make it work.
 
General_Specific said:
I can't get it to compile my scripts. What's up? It says that it can't find *.pyc.

EDIT: I found a solution, but it wasn't the batch file. I still don't know how to make it work.
Make sure that you have everything set up for it. You need Python installed, the global path set up (or added in the batch file), the mod path set up in module_info.py (using "/" instead of "\" in the path), and the folder for that path has to already exist (create it first of not).

The last command in the batch file deletes the *.pyc temporary files which are created by the python scripts compiling; if none of the scripts can compile for whatever reason, it will probably give you that error since it can find no matching files to delete.
 
:grin: I love you. I'm an extremley in-experianced modder, so this helped a bucket load. I'm sure it'll help others to =D

*Dives off to make mod*
 
General_Specific said:
I can't get it to compile my scripts. What's up? It says that it can't find *.pyc.

EDIT: I found a solution, but it wasn't the batch file. I still don't know how to make it work.

What's the error exactly? As far as I know the python scripts are never compiled to pyc, they're just run as-is by the python interpreter. Are you sure you got the 0.711 version?
 
Thanks for the feedback. Extra big thanks to Janus for pointing out the typo - it's been corrected.

Anyone else who finds this helpful, please post here, I'd really like to know if writing all this is actually worth the trouble or people would have been able to figure it all out themselves anyway. :wink:
 
It works great! Please get the next part of the tutorial soon. I'm working on a huge castle right now. I might post the final results later. :wink:
 
Man! How do you make the changes permanent? I made my castle and left, but when I came back it was gone. WHat is up with that?!? I pressed save changes!
 
General_Specific said:
Man! How do you make the changes permanent? I made my castle and left, but when I came back it was gone. WHat is up with that?!? I pressed save changes!

Hmm never had that problem before. Does this happen every time?
 
General_Specific said:
Every time. I can't find a fix. Am I doing something wrong?

Hm, let's take this to PMs, I'll post the problem once we've worked out what it is.
 
Figured it out! For some reason I had apparently forgotten to compile all of the scripts before I tried to modify the terrain. I tested it out, and it saved my changes. I'm back at making that castle.
 
General_Specific said:
Figured it out! For some reason I had apparently forgotten to compile all of the scripts before I tried to modify the terrain. I tested it out, and it saved my changes. I'm back at making that castle.

Glad it worked for you! I'm sorry I never received those files you sent me!
 
Back
Top Bottom