Some mechanics change

Lua is a fine choice as it’s very fast. Python is also interesting if you need a heavier library.

There are some games which relies heavily on Lua, and it would be interesting to see this. In Supreme Commander all high-level game mechanics are done in Lua. AI, units and other things are written in this. Essentially, the main game would be scripted in Lua, no different than an overhaul mod.

To add to the list of different types of modifications I would also consider cosmetic ones, particularly interface themes for those who want to change appearance and placement of buttons and things. These theme scripts could also have a resolution-switch callback which is called whenever a resolution is set and then places things accordingly. This way you wouldn’t need to have a special case for each resolution in the config, and you would also be able to have radically different UIs at the same time. The default interface would then preferably be implemented like such a script.

When it comes to selecting mods and compatibility you could have something simple, similar to Unreal Tournament’s mutator lists. If a player does not have a certain mod he could either be informed of it and denied to play, or he could download the mod as well as it’s dependencies.

Looking at a game like Oblivion there is another issue that needs to be cared for, when mods are clashing with each other. Like one mod changing the attack value of unit to one value, and another one doing the same. Would one of these mods be denied to do a change? Or should there be an order to their execution and if so, how do you determine who goes first?

Essential advantage of Lua is that H5 scripters, including me, are familiar with it. But I need to say Python’s features appear quite impressive.

Unreal mutators are nice as long the code is written in unreal script which allows easy overriding functions and classes, especially do it dynamically. Lua hardly supports classes and will do only what we (particularly myself ;)) define in a pre-made set of functions.
I’m afraid at current stage every mod could either use and overwrite already prepared configs / tables / properties or ship its own dll. Which may already give pretty good possibilities, but not nearly as versatile as UT engine is. Some of its interesting features is that ALL the objects derive from one root class - how could we compare?

Better yet, Lua has metatables and inheritance is not difficult to achieve. Reflection becomes trivial, as you’d only have to investigate a table if it contains the name of a function or attribute as a key.

I’d imagine new objects into the game like artifacts and units could be implemented by just making a metatable describing it along with callbacks that would be called by VCMI at appropriate times.

For example you could have an artifact give you 1000 gold per day, or a unit giving you 10*stack size gold every day just by adding a function like onNewDay to the table. VCMI would then at the start of a new day inspect all registered objects for an onNewDay function and call it.

@which goes first
there will be modlists for those
modlist is a simple list of mods in order (ie each line has mod name and those up starts first and those not in list don’t start)
there will be default.modlist for current best-for-user settings (a config file), named *.modlist for storing custom named sets (ie. tournament.modlist) and current.modlist for temporary save before game start (it’s a copy of default.modlist if user is a server and not choosen a ruleset modlist (mods has their own rulesets), it’s a copy of choosen custom modlist if user is a server and choosen one, it’s a copy downloaded from server if user is a client)

I think modlist file is much better than oblivion off-by-date-go

When two mods change the same value, it’d be quite hard to detect and prevent it. I think applying both effects will be the best solution if we don’t want to spend a lot of time on this issue. The effects of mods could be applied in alphabetical order.

but modlist has those, that we can format it ie like that

mod1name #ruleset_name_for_mod1 //comment1
mod2name #ruleset_name_for_mod2 // as always comment :)
mod3name //ruleset not needed
...

so we can include all vital information for configuration of start with easy wasy and support that using really tiny files (so almost no impact on network) and using “default” and “current” templates could also do for avoiding unneccesary overwriting of files aved by user and do so modlists and rulesets are always uptated by launching as client

That’s the issue. Imagine we host both HoTa and Wog 3.59f 9which we sure will do someday) and they both add new creatures to game. Now, how to manage it if they are all called by their index? Which creature has ID 200 and what happends when we call it? There are some ways to prevent conflict:
-Manage game content at global level, like we did here
-Refer to each object by its exact class name (or namespace) as it is in UT. But it would require rewritting almost huge part of code
-We can allow scripters to refer only by monsters’ name and then use some piece of code to find out which internal ID it has.

@majaczek

Could you describe you proposition more precisely? It has little to do with previous proposition so you should write what your mods / rulesets / modlists are.

@Warmonger

In my proposition, you couldn’t mix HotA and WoG if they were provided as games (what is the easiest option). To mix them, you’d need to base them on common game (make both HotA and WoG extensions to SoD by mods). Then everything is just the problem of compatibility of different mods.

The problem of identifying items from different mods can be overcome both easily and well. My solution is similar to your second option (I haven’t played UT so I’m not sure): everything we need to do is to change they type of ID from int to pair of two numbers - the standard ID we currently use and a hash of its source (hash of game or mod). Everything that changes in code is the initialization of that ID.

modlist refer to which mods to load and how (list of mods by name and arguments if needed)
to shrink unneccesary content on modlist you may provide only one legal argument - name of ruleset
ruleset is bind to some mod (choosen one of them), so they set constants, and initiate variables when they’re not set in mod or values need to alter
probably rulesets can also have some general entries ie.

 
reserve_castles 2 var1 // reserve two castles slots and bind index of first of them to variable var1
reserve_creatures n varn// same for creatures
at_least param1 value1// if limit for param1 is less than value1 then set it to value1, where param1 could be ie. max_morale min_morale min_luck Max_luck sec_skill_cap armorer:skill_cap

so they can get impact on mod which they are bind to

PS: It’s only raw idea, implementation may differ, but base is that modlists lists mods and binds rulesets, and rulesets are sets of rules for specific mods

EDIT: I forgot to say: mod is some pack/set of custom content with it’s original name, which also contains scripts and may be altered by rulesets, but mods can keep default values of what to set. So mod is a file like *.esp in oblivion (or some folder with data), but easiest implementation is a package done by commmon format and read by zlib or somewhat

PS: mod is loaded only when game process modlist and gets it’s name. when mod is not on list it is not loaded. ahh and rulesets is text based file in implementation, it can have commands and/or list to set variables, where commands are for engine to do something which is harder to do after loading mod than before, or something is liked to change outside a mod

Interesting idea. Could you write why do you think it’s better then my proposition?

because of control on the mods :sunglasses:
this point joins the aspect of rulesets and mods, but there also place for master game (as in your idea)

this is the idea of not splitting rules and mods as unmixable objects, but cumulative objects. It gives ease with basic configuration of mods and gives freedom for tweaking mods without change their inside. Also with my idea you can turn off mods temporary, and also you get control over conflicts (when merge of data is impossible, the latter mod wins)

edit: maybe there will be separate rulesets for base game ie.

 BASE #ruleset //ruleset for main game - only puts the changes in game as main game loads always first

edit: maybe we want mod mastering? ie. mod A use resource from mod B and thus need it so mod A in the mod package contains masterlist.txt which contain name on mod B and as mod A is child mod may put changes on mod B and use its resources

edit: if we get mod mastering then may be only one base but game differs as diffrent mods are main masters. remember that giving ability to mastering is giving the highest flexibility and gives chance to avoid doubling data (common data may be get out into master package). of course masters of mod can have it’s own masters

@mastering - there’s a need not only to list masters but IDs of data used/modified from those mod, so it’s created when creating a mod, and there’s no need to calculate dependencies in runtime (they’re saved with mod so it’s created once, used multiply)

EDIT: mod settings (modlist and rulesets) should be saved in savegame which is saved using them. If then each object from mod could get two integer based id ie

std::makepair(mod_id,item_id);

where mod_id is number of mod on the modlist, so we can get easy evidence on items. each item in mod has the item id and when mastering the masterlist gives pairs {master,item_id_in_master} so mastering then may be easy.
I vote for two integer based ids on pair(ui16,ui32) so it is enough and not too much

but then we need to do a “header compiler” which would give automaticaly itemIDs to each item in mod and exports itemIDs from master mods. Or we want to do not only game and mapeditor but we want to do modeditor too? so the modeditor should matter for all technichal things and gives people abilities to import and join things?

In Oblivion it’s done that each object have name and modeditor generates itemIDs when adding new thing and for game there are only numbers and items. Would we go this way?

  • by item i mean the most atomized data (the smallest chunk of undividable data)

The lack of control over mods (except on/off) in my proposition is not to make modder’s life harder but to make the concept of mods more clear. The mods should be designed to need no additional control to make choosing game’s options simpler but still powerful. If it occurs necessary, I could also imagine mods with one simple parameter (int / float in given range) but certainly no more.

As I wrote, I see no need in making mods configurable by user (outside of a very small range). Additionally, tweaking mods is certainly work for modder who is not afraid to change things directly in mod (changing things by GUI does not seem much simpler for modder; additionaly developers need to implement more mechanisms in application for choosing game’s option to make all things work).

In my idea you can do that easily too (by rulesets).

My rulesets could specify the sequence of loading of mods too.

the mod don’t NEED to have ruleset - it MAY have ruleset - if it has NOT ruleset then use mod default

EDIT: rulesets in my idea is for restating the mod without making new, the commands were only examples, maybe we don’t need them, so the ruleset would be only

somevariable=somevalue
someconstant=somevalue
somevariable=someglobalid

where globalids are things definied in the engine but mean the number ie. crabil::shooter, also on globalids can be done math (+,-,and,or,xor)

I think you merge two different things, which are game support for mods and configuration of mods. Here are my essential requests:
-All mods can be turned on an off and they do not require swapping or overriding files.
-If nessessary, mod has its own configuration file / menu accessible via main menu / VCMI engine.
-Gameplay mods (equivalents of mutators from UT) are avaliable to run together as long as they do not conflict each other in obvious way.
-New content (towns, creatures, etc) is free to use and access in any combinations.
-Scripts can be given and see ‘range’ of mods so that they may access objects only from current package, any specified package or all packages freely.

Now imagine (which is going to happen sooner or later) you are given all files from 3.59f and HoTA. They do not seem to alter gameplay in significant way, just add more game objects and a bunch of new functionalities. How to use them both at same time?

How? VCMI final would be equivalent of wog3.58f/SOD
there will be master package for 3.59 and master package for hota
the master package contain also indexes for all in.
if mod depends on hota it need hota as a master and there must be a header to acess elements from master. same for wog 3.59. each mod has an index too. If mod has elements related to itself content the package has a number translate file (part of header), based on that if it refers to self it gets number from self and choosen item whith it’s number. if mod element depends on other mod, there will be list of masters (1st master second master etc.) which are translated to positions of those masters on modlists. Mastered item can be used or modified. game will calculate those virtual adresses 0xhhhh:0xhhhhhhhh (those pair of ids i mentioned) based on modlist and masterlist in any used mod. modlist, masterlist, and state of data from mods will be saved in the savegame. As mods can’t change during gameplay the IDs calculated on start will be still proper.
So if hota is a mod then if it refers to self it always refer to self not depended on hardcoded town ID. if mod refers to hota then it has it in own masterlist. if mod doesn’t refer to hota it sees almost as if hota weren’t there, so it can access only a data “addressed” in masterlist. for unity purporses the original data from heroes 3sod+ab should be treated as master package.
so if wog3.59 refers to h3sod but not to hota then it hasn’t hota in masterlist and is blind for hota data. item ids should be automaticaly created when adding those item to package, the mod id is diffrent in package and in game (in mod it’s based on masterlist in game it’s based on modlist and it’s translated by starting game). when needed savegame may also access to the low level ID for simplier serializing, but anything based on relations ie. scripts must call by paired-ids. So those is somewhatmeta interface. Almost the same mechanics is done in the bethesda game called Oblivion (it has wrong that it is based on time of mod, and there’s no simple ruleset, so you must add next mod and by bethesda number of mods is limited to 255 including the main game package), and bethesda have formated mods as databases not as regular packages, but maybe easier is adding files to package and to calculate header file, just before packing in normal package (zip/rar/7z)

so all bases on dependences - if somewhat is not mastered it can’t be changed/used. so the worst we can get on this model is having two the same items in two mods so game thinks it’s not the same. And somewhat merge will be nice eg. if there’s list of monsters to use for some script, and then 2 mods tries to add diffrent items to that list it’s more wise to give game the content in main list + from mod 1 + from mod 2 than overwriting change of mod1 by change of mod2

PS: I don’t know if I written all I want… these were huge part of english :unamused:

some more:
-it not overwrite files as if files has the same path it has the path in diffrent packages
-for editing rulesets there may be interface files, but rulesets can change some hidden options

  • in this way if there’s conflicts they’re walked around (so conflicts are virtual, or are known and resolved with specific positions on modlist)
  • script generally can access only the package itself or package which the package has as an master, but there’s some global commands which can refer to any ingame content (ie. scripted spell can do damage don’t knowing about the monsters which is added by another mod because of calling global function “do_damage some_damage_counter_function somehexlist”)

PS: I still think that I have something nto remembered, but it goes not today

The code does not necessarily have to be rewritten. When the games loads it’s objects it should first read the base data files, yielding the same assignment of IDs each time. Next the new objects from activated scripts are read, and are assigned the next free ID number which is more dynamic as the ID assigned depends on what order the scripts are loaded.
So it would be possible to get away with the hard-coded stuff since it only concerns the base SoD/WoG files that are going to have the same IDs anyway, whereas scripters would be forced to deal with their objects by referring to them by name.

From a scripting perspective, I think the most important thing is to be able to easily access all the information about new creatures, monsters, towns, etc.

For example, if I were to write a script that gives you extra resources when you defeat a monster stack on the map, and the type and value of resources depends on the level and number of monsters (or perhaps their total health) and also on individual factors (e.g., more wood from Dendroids, crystal from Crystal Golems, Mithril from Magic Elements, etc.) I would need to know the current number of creatures in the game, their level, health etc. Obviously it would be tricky for me to customize resource types for completely new monsters that another mod or script adds but as long as I could get the basic info about them my script could handle them in a more generic but still logical fashion.

Referring to custom creatures by name is fine if that information is known (and can be easily retrieved by te script for comparison). But in the case of unknown creatures, they would obviously need to be referred to by their list number in most cases. This is especially true for randomly generated results.

Basically, the key element here is that if there’s new monsters, the scripting language must provide a method to get the current number that are in the game (and then retrireve all needed details for any monster, new or old). If there are added towns, the number of towns must be available to the scripts, and again, details for them easily retrievable. Likewise with new artifacts, resources, creature banks, mines, heroes, hero types, skills etc. If there’s already some of them in the game, we’ll need to know how many new ones there are, what their ID and names are, and all the other details too.

For example, a script that gives a random skill shouldn’t need to be rewritten for every skill that’s added by another script (assuming that adding new skills through scripts will be possible in VCMI). If the information about the number of current skills can be easily accessed then a good/dynamic script will call a function to get the current number and then randomly choose from the entire range (assuming this is desired).

On a related note, some of the existing internal lists already require some hoop jumping to use. For example, the monsters list includes several “not used” numbers that WoG scripts had to skip over when generating a random creature. Furthermore, a few of the Fortress creatures aren’t in the same order as the other town types, and Conflux is also a bit different. While it may be necessary to maintain this internal order (for a variety of reasons), perhaps it would be possible to create a second shadow list of monsters that would eliminate the discrepencies of the regular list and could thus be accessed more easily by scripts.

Okay, enough post-midnight ramblings for me. :slight_smile:

EDIT: Sorry about the double post there…for some reason it didn’t seem to log me in properly the first time and doesn’t seem to be a way to delete the “Guest” posting.
EDIT 2: Thanks for deleting the double post, Steven. :slight_smile:

My idea for it is simple: diffrent classes ingame for specified objects (ie. monster from hota mod) and for general objects, where general objects may need to have accesible container, also there need be some global “pointers” (so we can get somehero:allinarmy also currenthero:allinarmy and currentbattle:attacker:allinarmy:onlyalive or currentbatle:defender:allinarmy:onlydead and battleend:attacker:casualities or battleend:winner:gainedexp or battleend:loser:casualities), so if we process containers we have access for element from any mod changing default container (or container defined in common master mod)

@majaczek

You’ve described your idea very chaotically. Could you write everything from scratch focusing on clearness?

@fnord

The amounts of different things are easily accessible in the engine. We’ll try to expose as much information to scripts as possible but I can’t talk about details now since currently we are not developing this part of engine.