A New Form of Modding – Smart Module

Users who are viewing this thread

My GitHub is here, however it is in Chinese...: scottish-fold; and this is a mod being made based on the very tool: just go to this Prosperous Empire which I finished translation today and it is much better than the 80% machine translation below... Do not go into the scottish-fold one tho 'cos it's bloody ages ago, the Prosperous Empire is new.

and stars are of course welcomed!!!

#Scottish Fold: a simple and fast production tool for the script of MnB.

###foreword
---
Well, you can actually skip this part as it is just some b**locks.

Ages ago, when I first started playing MnB, I wanted to be able to make my own script, or well, mod, to tell the story I wanted to. When I started doing that with a great passion as a dream, I found that it is not as simple as I thought. The largest problem that I face is I need to learn python the language, as well as MnB’s own Module System. That's too complicated for nude like me. It's just way too difficult to make even one function. Even if one merely want to add one’s own castle to the game, one need to learn a lot of code in order to modify a lot of code. After countless tests, one can only display a small castle on a huge map (when the first time I successfully added my own castle, I was so happy because it is just too hard). So, considering it is already this hard for one to add a simple castle, what if one want to add a whole faction? That's a lot of complicated code. Adding a person, a castle, a country, or even a complex function (farming, opening a shop, managing a village, managing a castle, patrolling, formation system, banking system, recruiting and landing robbers, title system, officer system, being a king, diplomacy between countries, etc.) to our ideal map requires learning loads of code and watching countless tutorials can but produce a little bit of results. When one finally gather enough courage and time to open the introductory tutorial and the functional codes of various great modders, one will find that the original code is so long and difficult to understand, and can not be solved with courage and time. Therefore, my idea here is – can we not make modding this complicated, can we just modify a small bit, and then generate the grand system I want?

Then started I to find, and found many tools, they are really some brilliant tools, which saved a whole lot of my time (as a 7th grader in China, time is really important), nevertheless, once I start to think about another mod, I find that these things are to be copied and pasted another time, and some functions cannot be even used – yea, I cannot even do copying good… One just need to take care of some many things as merely being slightly unconscious may lead to it cannot be used. Sometimes when they are finally solved, more complicated issues like the import of models; animations and such came to the surface. Therefore I thought if we can make mods even more simply? I am merely one who wants to tell stories, why can I not put my focus to the plot? And why can it be god-of-coding who can create mods?

For quite long a time, the thought of making a mod is stopped by the complicated coding…

Just last month as we are all have very much nothing to do in home because of coronavirus, I created such tool and started developing a mod Prosperous Empire with it: Scottish Fold.

---

### Tool Intro
I divide the users of this tool into 2:
Tool maker – they help developing this tool, need loads of coding;
Mod maker - they create mods and plots, need no coding at all but copying & pasting

This is a tool without a GUI. The maker just have to edit the ‘config.py’file, and the system of this tool with help the maker to generate a lot of code. Therefore to the maker, they only have to know about this file only, and others are the mission of tool makers.

So, there is a file ‘module’ in the tool, which contains every function in one py file, containing strings, scripts, trigger, constants, etc. That is, creating a function, one needs to create one py file, and define a dict variable in it. In the dictionary, every key represents a collection of data, and cannot be randomly defined. This will be talked about soon in the grammar of module part.

I am afraid that this tool will have loads of issues as previous tools, therefore I wish to fulfil all functions of one of the mods I made again, to write each module one by one. After a period of time when I finally finished the Patrols function, and that the user of the module can change some parametres, which makes quite big an effect on the module.

#### The use of the tool
- Nearly 0 Coupling
- Simple Enable/Disable
- Module Function
- Simple Merge of Function
- Unified Code
- Easy to test
- Code Independence
- Detailed Complication log
- Reduced Error Rate
- Extremely Simple 'Transplant'
- Increase in code volume
- May be a lot of bug

#### Modules
In this tool, each function is a module, and each module is a separate file.

Steps to writing a module:
- Create a .py file in the modules folder;
- Define a dict (Dictionary) variable in the .py file. Please refer to the module syntax when writing the function;
- After the function is written, add the dict variable to config_modules.py In the modules collection in the file;
- Modify export_dir in module_info.py as your game directory;
- Execute build_module.bat (Windows) or build_ module.sh (Linux or macOS) script

#### Module syntax
Not to put too fine a point on it, a module is a dictionary (hash table) type variable, which contains all the functions we write. Each item represents a specific information or operation.

*name*
The meaning is very simple, that is, the name of a module, to ensure the global uniqueness.

*enable*

Whether the module is enabled, that is, whether the script is added to the game at compile time. If this value is not specified, it will be added to the game by default. Therefore, to disable a function, you only need to change this value from true to false. After compiling the game, the function of this module will not appear in the game.

*dependentOn*
If in the process of writing a game, one may find that some scripts have already been written, and one can use them directly in the script, but one need to add the name of the module where the script is located to this list. No errors will be reported if you don't join, but after joining, the tool will help you to check if the dependent module is involved in the game compilation and give you timely reminders.

#### Content of each game item
To put it bluntly, the script adds our own custom code to the module_system, including, troops, items, dialogs, strings, scripts, etc. They are also an item level and 'name' and 'enable' are at the same level in this tool, and since each operation is the same, I will only introduce one of them and the rest of the reference function modules.
For this system, each module item has an append, delete, insert, replace function.
For example: add a string item to module_strings.py; rewrite the game_get_troop_wage feature in module_scripts.py; add a trigger to the visit_town_castle battlefield controller for the module_mission_templates.py file; add a new option after the continue option in the start_game_0 menu in module_game_menus.py to test the script, etc.
I've boiled them all down to five operations: add, delete, insert, replace, sub operation (children).
Before introducing these features, we need to introduce a new concept, SIGN (Signals, which can actually be translated as selectors).

*sign*
Signal (selector): suitable for deletion, insertion, replacement functions (add not required, just add to the end of the data, no selector required)
There are four types of signals:
1.id
Also called Simple Selector, uses the ID of the data as a selector, e.g., (ID of player, ID of Swadia camp: kingdom_1) for data selections with ID.
2. Subscript
Note: The subscript starts at 0!!!
Also called subscript selector, it uses [# of numbers] as a selector, e.g., (first data of troops troop set: #0, 10th data of factions camp set: #11), applied to a column of data.
3. Complex
The complex selector is divided into two main parts.
For example (dialogue).
[anyone, "member_castellan_pretalk", [], "Anything else?", "member_castellan_talk", []], Part 1: is a selector, e.g., member_castellan_pretalk:member_castellan_talk, note: the symbols are separated by a colon (English symbol).
Part II: is a subscript selector, e.g., [1,4], note: square brackets are used outside the symbols and commas are used to separate the symbols from each other (English symbol)
Full format: member_castellan_pretalk:member_castellan_talk:[1,4]
The format of the selector means that the data is selected from the 1 subscript and 4 subscripts in the data, spelled into a new string against member_castellan_pretalk:member_castellan_talk, and if equal means selected to, and if not equal means no data was selected.
Complex selectors are applied to data rows without IDs, from which n (logically infinite) data are selected to form ID-like symbols. so that it can be accurately located within the data set.
4. Complex - qualified
The only difference is that each selector (the first part) can add an @ symbol at the end. The meaning of this symbol is: ask the selector to do some special treatment on the subscripted data, first, convert the special symbol (if not letters, numbers, underscores, these three symbols, all other symbols are special symbols) into underscores, second, use the beginning match, that is, we do not have to list the value all, just list the beginning part.
For example: member_castellan_pretalk:Anything_else_@:member_castellan_talk[1,3,4], I put the @ symbol after **Anything_else_**, which is telling the system, please do special processing on the data that is being compared to me first, and then compare it to me. This form is suitable for very complex situations.
After understanding the SIGN selector, we can learn to operate the command.


*append*
The append command corresponds to the data type List, the end of the data set that is appended to the data stored in the list.

*delete*
The delete command corresponds to the data type List, which stores the sign collection, which is the selector collection, and is deleted from the data collection as soon as it is selected.

*insert*
The insert command is actually two commands: insertAfter and insertBefore.
The data type corresponding to the insert set is list and the data stored in the list is dict.
InsertAfter contains two parameters.
sing: Specify a selector.
data: Specifies the data set to be inserted
insertBefore has the same arguments as insertAfter, except that insertBefore adds data to the front of the data line to which the selector belongs, and insertAfter adds data to the back of the data line to which the selector belongs.

*replace*
The replace parameter is the same as the insertBefore command. The difference in behavior is that the selected data is deleted and then added to the front of the data corresponding to the selector.


To better understand the command, take strings as an example of adding data (the writing of attributes such as name, enable, etc. was omitted for simplicity).
---
Python:
"strings":{
    "append":[
        ("s5_s_patrol_party","数据会被添加到strings集合的末尾"),
    ],
    "insertBefore":[
        {
            "sign":"empty_string",
            "data":[
                ("test_string_insertBefore","在empty_string后方插入数据"),
                ("test_string_insertBefore2","在empty_string后方插入数据"),
            ]
        }
    ],
    "insertAfter":[
        {
            "sign":"yes",
            "data":[
                ("test_string_insertAfter","在yes前方插入数据"),
            ],
        }
    ],
    "replace": [
        {
            "sign": "empty_string",
            "data": [
                ("empty_string", "替换id为empty_string的数据"),
                ("empty_string2", "会被插入在id为empty_string的后边"),
            ],
        }
    ],
    ## 删除id为color_no_1的字符串,删除strings集合中第109个的字符串
    ## 删除复合选择器(从下标为0和1取值拼成字符串与【no_string:NO_STRING_@[0,1]】作对比,如果符合就删除)
    "delete":["color_no_1","#108","no_string:NO_STRING_@[0,1]"],
},
---

If you want to see more how to use it, please refer to: Features folder

---

At last:

PyCharm 2018.2 (IDE tool for python)
python2.7
Batch Scripts support (for executing bat files, downloaded in the plugin library in pycharm)
github (used to save code from being lost forever)
git (tool)

Basic modules.
Military module: provides functions related to the military (e.g. [NPC random name, only Chinese name supported], [play king and lord function])
Corps module: provides functions related to positions and corps (e.g., [Corps creation in various situations], [Soldier recruitment], [Experience increase], [Captive sale]).
Camp module: provides camp-related functions (e.g., [number of enemy countries])

Test Scenarios (constantly updated): lots of test scenarios for testing the game, quick access to test areas (random battlefields, direct access to large maps, castles, taverns, arenas, streets, can play as a king or lord, etc.)
Patrols (completed): create patrols for positions (capital (6 teams), towns (4 teams), castles (2 teams), villages (1 team)) and maintain soldiers automatically.
Patrols [Remastered] (Completed): Honor determines the number of patrols, the lord's dominance and coaching skills determine the military strength of the soldiers (requires a lot of money), and there will be no patrols in a territory without a lord.
Heroes Gathering (being updated): in addition to players, NPCs (random names, with children) seeking wealth in Kaladia, attacking robbers, running businesses, joining nations, becoming self-reliant, recruiting soldiers, etc.
Army Management (being updated): there will be a number of positions in the army, granted to companions, each of which manages different things, such as: adjutant, counselor, medic, veterinarian, armament, cook, siege master, coach, etc.
Princess Outing (Completed): Instead of waiting in the castle for her husband or brother to return, the lord's women go out in boredom and take out a few robbers.
Village management (continually updated): taxation of strongholds is increased and villages are allowed to stockpile troops.
Tax Enhancements (already completed): increase taxes on towns, castles, and villages as fundamental to the administration of the lord's army.
Lords Collect Rent (Completed): Lords automatically collect rent from villages for the maintenance of castles, troops, companions (not completed), patrols.
Overlord Character (Completed): shows the character of all overlords.

If you do have some ideas, pls post it here or even write the code for this tool to help more people, for I really have no loads of time. ? Cheers!
Hope you like the convenience of this!
 
Last edited:
To let me get this straight: You find things like adding a new castle too complicated but you are able to program a whole new tool which can make those edits on an easier way?

well... ?
I am tho still not quite good at ms - not as good as you certainly, but I learnt more and more since a few months ago when I started doing this. And to answer your question... It is apparently not easier and it took a huge amount of time from me and my friend, but I merely made this because of I think that this may help many whilst creating more mods from other people.
Cheers for replying!
---
And here, I realised that this may be a bit too complicated and full of nonsense, therefore I will just talk about it simply:
I created a system which one merely have to put codes of one function into a module file, and change nothing in all those .py scripts in the file that one needed to change afore.
Now, I sincerely want some god-of-codings to help me on this... To test it, or use it so as to find more bugs & issues; or even to write more functions with me and my friend – however, I wish that the codes can be open-sourced... Hope you understand.
 
Last edited:
Back
Top Bottom