Jump to content
Sign in to follow this  
rübe

Let's talk about CfgVehicleClasses

Recommended Posts

Let's talk about CfgVehicleClasses

(...or how to get rid of classnames)

CfgVehicleClasses (or config.bin/CfgVehicleClasses in full) has been introduced with Armed Assault as "the new way of using custom vehicleClasses". Great. So what's that actually good for? VehicleClasses are the categories available in the editor (see https://community.bistudio.com/wiki/File:Cfgvehicleclasses_result.jpg) to put down some vehicles, which have a config entry vehicleClass that refers to exactly one such vehicleClass.

Let's have a look at it.

This is what CfgVehicleClasses currently looks like:

rkfWTZw.png

Full list of (currently 97) vehicle classes:

Men, Animals, Car, Armored, Air, Support, Camera, Objects, Ammo, Sounds, Mines, Ship, Static, Backpacks, Autonomous, Submarine, Uniforms, Wreck, Wreck_sub, Anomalies, Afroamerican, Asian, European, MenRecon, MenWood, MenSage, MenSpecFor, MenUrban, MenSupport, MenSniper, MenDiver, MenStory, Women, Armory, Targets, Test, Locations, Modules, Emitters, WeaponsPrimary, WeaponsSecondary, WeaponsHandguns, WeaponAccessories, Magazines, Items, ItemsHeadgear, ItemsVests, ItemsUniforms, Intel, Virtual, Cargo, Container, Garbage, Flag, Submerged, Lamps, Communication, Helpers, Dead_bodies, Furniture, Military, Misc, Signs, Small_items, Training, Shelters, Fortifications, Tents, Market, Structures, Structures_Commercial, Structures_Cultural, Structures_Industrial, Structures_Infrastructure, Structures_Military, Structures_Town, Structures_Transport, Structures_Village, Structures_Walls, Structures_Fences, Structures_Slums, MenVR, Objects_VR, Structures_VR, SystemLocations, SystemSides, SystemMisc, MenArmy, MenSLA, MenRACS, MenCIV, Objects_Sports, Structures_Sports, Explosives, Respawn, Objects_Airport, Structures_Airport.

So..., what's wrong?

  • VehicleClasses all inherit directly from CfgVehicleClasses (check for yourself with configHierarchy), thus CfgVehicleClasses is an unordered set. No hierarchy. No relations.
  • CfgVehicleClasses is full of overlapping and ambiguity (...and bear in mind that each vehicle points to exactly one vehicleClass). Prominent examples:
    • Men, Afroamerican, Asian, European, MenRecon, MenWood, MenSage, MenSpecFor, ..., MenStory, Women.
    • Military, Tents, Structures_Military, Fortifications
    • Market, Structures, Structures_Commercial, Structures_Cultural, Structures_Infrastructure, Shelters, ...
    • Structures_Town, Structures_Village, Structures_Slums, Structures_Fences, Structures_Walls, Garbage, Lamps, ...
    • Structures_Transport, Objects_Airport, Structures_Airport
    • Misc

Good luck finding the "correct" vehicleClass for your vehicle. :p

And even worse: going the other direction to have a look at all children/vehicles of some vehicleClass doesn't offer much value. On the one hand the vehicleClasses are too broad, including many vehicles that should be in a "different bag". And on the other hand many vehicles are still scattered over many funny vehicleClasses (e.g. to get the set of all tools like a hammer, you probably also want to look at "Cargo" and not just "Small_items", yet both vehicleClasses include many other and very different vehicles).

CfgVehicleClasses is completely broken in it's current state. And I think it even shows for its intended/original purpose (making it easier to find and put down things in the editor).

Great. ...now what?

CfgVehicleClasses should be a hierarchical tree. Not a flat one. You might think: "...but wait, we already have that, and it's called the friggin config, you silly dummbatz!" Well, yes. But this is different. The (original) config is for the game-engine, inheritance is "funny at times" (to say the least), and extracting meaningful information from it is rather hard at times (have a look at functions_f/a3/Inventory/fn_itemType.sqf), if not impossible. There's a reason CfgVehicleClasses has been introduced in the first place. We need semantic/meaning!

This is what CfgVehicleClasses should look like (vehicles are only allowed to refer to leafs!):

tMoahQK.png

  • Overlapping and ambiguity is solved with similar/equivalent leaf-nodes under different paths or parent nodes. E.g. there is a team leader (TL) for regular, recon and divers (or whatever special branch/section). A leaf-node together with it's inheritance (or path) is nice to work with to collect/filter all kind of vehicle-sets in a meaningful way.
  • Better granularity/detail of vehicleClasses! Having a proper CfgVehicleClasses (instead of just something shoehorned for the editor/UI) would mean that BIS could finally stop to encode meaning into the classnames! Currently parsing for "_tl_", "_gl_", "_ar_", "_aar", ... (or maybe parsing displayName, buaha) is the only way to get at the role of a soldier. And it breaks as soon as you try some community addons. :(
  • A tree is a well known UI control and can be easily implemented for the editor - the original need for CfgVehicleClasses. The proposed structure of CfgVehicleClasses should allow for a much better interface anyways (different grouping strategies). And in the end, this could also be the interface to put down semantic entities (say a TL) of some faction instead of hardcoded classes.

The resulting problems are few and can be managed, I suppose:

  • Using custom vehicleClasses needs to be restricted, if not forbidden (make better selection by faction). If addons implement unknown paths in CfgVehicleClasses, then we're back to where we've started and can't reliably parse any addon for the assets/stuff it offers. In the example above, the level above the leaf-nodes (regular, recon, diver; i.e. the branches/sections) could be extended. Maybe. Yet, the same standard leaf-nodes (for soldier roles here) need to be used again.
  • The structure (or vocabulary) of this tree is one huge problem in and on itself. IMHO this should be openly discussed (devs and community), and once (re-)introduced only extended after careful considerations (your typical language consortium, hehe). Still, requests for new vehicleClasses should be possible (instead of allowing "custom" ones).
    Still, anything is better than what we currently have. And I think - at least for the roles of soldiers - the infixes introduced by BIS (tl, m, lat, exp, fac, ...) are a good starting point. A similar, and similarly generic thing needs to be found for actual vehicles, that works for any (reasonable) era (I'm thinking of leaf-nodes along the lines of: AA, AT, Transport, ... under different vehicle branches/categories wheeled, mechanized, air, sea, ...).

I've tried to have this discussion once already (see: Towards better plug'n'play (...or configFile as an ontology)), but I couldn't really pinpoint the problem, nor a solution at the time. Thus that wall of text didn't result in anything.

Ultimately the idea is still the same: we need to get rid of classnames. Addons (e.g. AI-modifications, modules, ...) are supposed to work on any map. Missions should be played with any factions. So let's stop hardcoding classnames and let's plug'n'play!

N.B. Given that the current CfgVehicleClasses is just a hack for the editor, I'm confident such a change is feasible (without breaking much, if anything...), maybe even for A3 (maybe not :(). IMHO the hard work here is the vocabulary, hence it might be good if we could already slowly come up with something reasonable?

Btw. who over at BIS is chef de la config anyways? :u:

...let him know I've asked for him. :rthumb:

  • Like 1

Share this post


Link to post
Share on other sites

At first it looks like you want to get rid of the config classes inside the actual config file, which I can't see how would ever work. Inside the config file there is also a very logic inheritance from the base class to different sub classes to actual units. Makes perfect sense.

If you are talking about using the class names in missions, or rather remove the classnames somehow, I can't see that it is an easy fix if possible at all.

Using custom vehicleClasses needs to be restricted, if not forbidden (make better selection by faction).
How could an additional unit (addon) be defined without it's own class name?

If you want some kind of standard way of writing classnames so you can find a particular type of unit with a script, regardless of what addon it comes from, I can't understand how that standard would look like as each unit needs its own unique name to be defined.

I think I understand but what I think you are asking for is so strange I might be competely wrong. So if you could please explain it short and simple for me?

Share this post


Link to post
Share on other sites

you wont get rid of overlap by making inheritance. Just an example: The term Soldier or Civilian is not gender specific, and if we had women in the game, you would need an extra soldier/civilian class and it's subclasses for those inside both men and women class.

Same with other stuff, so you are replacing a loose flat structure with a inheritance structure that is totally arbitrary, while still having overlap. I don't see the advantage... They are basically just tags, so it would be better to keep the flat structure and assign an array of cfgvehicleclasses to a vehicle class instead.

vehicleClasses[] = ["Men","Asian","Recon","SpecFor"]; //asian spec ops sniper
vehicleClasses[] = ["Structure","Military","Communication"]; //radio tower

Edited by X3KJ

Share this post


Link to post
Share on other sites
At first it looks like you want to get rid of the config classes inside the actual config file, which I can't see how would ever work. Inside the config file there is also a very logic inheritance from the base class to different sub classes to actual units. Makes perfect sense.

Except for the vehicleClass entry on vehicles the actual config-tree is left untouched. Just the CfVehicleClasses subtree is supposed to be redesigned in order to get a better layer of abstraction.

I guess an example wouldn't hurt (if you guys want I can post the code I'm running with so far, but it's in a state of flux, so I'm a bit reluctant...).

Anyways, here we go:

  1. Step one is to retrieve a list of all factions currently available (incl. basic attributes such as: class, priority, side, icon, flag, ...) and to extract all assets from a faction, which is the easy part.
  2. The next task is the hard part: making sense of those assets (and ultimately getting rid of classnames - bear with me). For each faction we want to have a dictionary of standardized keys (e.g. infantry roles) pointing to the actual classnames, s.t. we can use the standardized keys for any faction, without having to care about concrete classes.
    Excerpt from the default section/branch of BLU_F:
             men(35):
                __DEFAULT = ["B_Soldier_F"]
                unknown = ["B_Soldier_02_f","B_Soldier_03_f","B_Soldier_04_f","B_Soldier_05_f","B_Competitor_F","b_soldier_survival_F","Underwear_F","B_support_MG_F","B_support_GMG_F","B_support_Mort_F","B_support_AMG_F","B_support_AMort_F"]
                r = ["B_Soldier_F"]
                rangemaster = ["B_RangeMaster_F"]
                lite = ["B_Soldier_lite_F"]
                gl = ["B_Soldier_GL_F"]
                ar = ["B_soldier_AR_F"]
                sl = ["B_Soldier_SL_F"]
                tl = ["B_Soldier_TL_F"]
                m = ["B_soldier_M_F"]
                lat = ["B_soldier_LAT_F"]
                medic = ["B_medic_F"]
                repair = ["B_soldier_repair_F"]
                exp = ["B_soldier_exp_F"]
                hpilot = ["B_Helipilot_F"]
                a = ["B_Soldier_A_F"]
                at = ["B_soldier_AT_F"]
                aa = ["B_soldier_AA_F"]
                engineer = ["B_engineer_F"]
                crew = ["B_crew_F"]
                officer = ["B_officer_F"]
                pilot = ["B_Pilot_F"]
                hcrew = ["B_helicrew_F"]
                paratrooper = ["B_soldier_PG_F"]
                uav = ["B_soldier_UAV_F","B_UAV_AI"]
                unarmed = ["b_soldier_unarmed_f"]
                sharpshooter = ["B_Sharpshooter_F"]
                heavygunner = ["B_HeavyGunner_F"]
                survivor = ["b_survivor_F"]
                universal = ["b_soldier_universal_f"]
                aar = ["B_soldier_AAR_F"]
                aat = ["B_soldier_AAT_F"]
                aaa = ["B_soldier_AAA_F"]
                spotter = ["B_spotter_F"]
                sniper = ["B_sniper_F"]
                ghillie = ["B_ghillie_lsh_F","B_ghillie_sard_F","B_ghillie_ard_F"]
    

    Thus, instead of createVehicle ["B_Soldier_GL_F", ...]; we'd rather call a function ["BLU_F", "GL"] call spawnUnit;. Instead of hardcoding the classname, use the faction-key and the role-key instead. That's the idea.
    And it's nothing new: such lists as shown above have been put together and maintained by so many people. Manually! It's a shame. We need reliable means of extracting this stuff automatically at startup.
  3. Given such a tagged list of assets, we can build up definitions of groups (CfgGroups is useless...) for all factions, while only groups get registered for which all required assets are defined.
    Somethink like this:
             groups(15):
                __DEFAULT = nil
                squad = [[["sl","LIEUTENANT"],["medic","PRIVATE"],["tl","SERGEANT"],["ar","CORPORAL"],["aar","PRIVATE"],["lat","PRIVATE"],["tl","SERGEANT"],["ar","CORPORAL"],["aar","PRIVATE"],["lat","PRIVATE"],["tl","SERGEANT"],["m","CORPORAL"],["a","PRIVATE"],["lat","PRIVATE"]],[]]
                fireteam = [[["tl","SERGEANT"],["ar","PRIVATE"],["gl","PRIVATE"],["lat","PRIVATE"]],[]]
                fireteam_at = [[["tl","SERGEANT"],["at","PRIVATE"],["at","PRIVATE"],["aat","PRIVATE"]],[]]
                fireteam_aa = [[["tl","SERGEANT"],["aa","PRIVATE"],["aa","PRIVATE"],["aaa","PRIVATE"]],[]]
                fireteam_mg = [[["tl","SERGEANT"],[["heavygunner","ar"],"PRIVATE"],[["heavygunner","ar"],"PRIVATE"],["aar","PRIVATE"]],[]]
                fireteam_exp = [[["tl","SERGEANT"],["exp","PRIVATE"],["exp","PRIVATE"],["exp","PRIVATE"]],[]]
                sentry = [[["gl","CORPORAL"],["r","PRIVATE"]],[]]
                sniper = [[["sniper","SERGEANT"],["spotter","CORPORAL"]],[]]
                mot_patrol = __CODE
                tank_section = [[],["tracked_mbt","tracked_mbt"]]
                tank_platoon = [[],["tracked_mbt","tracked_mbt","tracked_mbt","tracked_mbt"]]
                tank_platoon_aa = [[],["tracked_mbt","tracked_mbt","tracked_aa","tracked_aa"]]
                tank_platoon_arty = [[],["tracked_arty","tracked_arty","tracked_arty","tracked_arty"]]
                tank_platoon_mlrs = [[],["tracked_mlrs","tracked_mlrs","tracked_mlrs","tracked_mlrs"]]
                air_squadron = [[],["airplane_bombing","airplane_bombing"]]
    
    

    And now we can spawn "fireteam" from any faction without having to hardcode a single class. Wait, that's the next step already.
  4. Spawn stuff in a meaningful (tagged) way from any faction:
    [
    	["type", "aar"],
    	["section", "main"], // could be "recon" or "diver"
    	["faction", _faction], // faction dictionary with assets (maps to actual classes) and that stuff
    	["group", _group],
    	["position", _pos]
    ] call spawnUnit;
    


    ...and then:

    [
    	["type", "fireteam"],
    	["section", "main"], // could be "recon" or "diver"
    	["faction", _faction], // faction dictionary with assets (maps to actual classes) and that stuff
    	["position", _pos]
    ] call spawnGroup;
    


    You don't spawn (or put down in the editor) 4 hardcoded unit-classes. You just spawn/put down a "fireteam" of that (or that) faction.

  5. Last step: let's have a dialog to pick from the available factions before a mission starts (maybe filter/check for required assets first). Imagine you could just download a new faction-addon and use them in your favorite missions! That's the kind of power such an abstraction would offer.
    Now don't get me wrong; many people still will want to "hardcode" many aspects of their missions. Nothing wrong with that. But things aren't black or white: you could design a mission in such a way that the player-faction is hardcoded, but you could still choose from a pool of enemy factions to play against.
    And this is just the example for faction-assets. The same applies to objects/structures with respect to modules and AI-mods and such stuff, where again, we need to get hold of the "type"/vehicleClass of an object and don't care about specific classnames. If some module is supposed to populate the map with civilians in a meaningful way, then that module should not contain a hardcoded list of assets. That module should also work on new maps with new objects (but same old tags!).

In order to extract these lists of assets for all the factions I currently rely on current CfgVehicleClasses and then the classnames themselves mostly, because BIS choose to encode that meaning with those infixes there (_a_, _aa_, _aaa_, ...). This somewhat works fine with default BIS assets, but obviously will break for virtually any addon plugged in. Community addons define their own CfgVehicleClasses (e.g. RHS makes heavy use of this) and then that unofficial _infix_ standard isn't adhered to either. Of course not. Best we can currently do is super fragile, or simply a lot of work manually writing those lists down.

So if you could please explain it short and simple for me?

Was this better/more clear now?

I'm afraid, I seem not to be able to serve with "short" (feel free to call me mr. wall of doom :().

you wont get rid of overlap by making inheritance. Just an example: The term Soldier or Civilian is not gender specific, and if we had women in the game, you would need an extra soldier/civilian class and it's subclasses for those inside both men and women class.

Yes. But that kind of "overlap" is no problem. There can be equivalent nodes (or tags) in different sub-trees. So you have a soldier and a civilian branch under men and women. And it's no problem to set the correct leaf-node as vehicleClass for your vehicle (so there's no overlap in multiple leaf-nodes that would all be equally suitable; hence the overlap "in vehicleClasses").

But yes, the actual structure of such a tree is rather difficult and rather arbitrary.

They are basically just tags, so it would be better to keep the flat structure and assign an array of cfgvehicleclasses to a vehicle class instead.

vehicleClasses[] = ["Men","Asian","Recon","SpecFor"]; //asian spec ops sniper
vehicleClasses[] = ["Structure","Military","Communication"]; //radio tower

Good point. But now you've just lost the power of inheritance and the relations between vehicleClasses (the whole "is-a" chain back up to the root). Well, this might be a fair price to pay; but considering CfgVehicleClasses is a hack just for the editor in the first place, it might be worth to keep a tree. How would you present all those vehicles in the editor with only an array of tags for each vehicle? Hmm, granted, such hierarchies (or hierarchical trees) could be induced on the fly by picking one tag after the other, so yeah... that might indeed be a better solution.

Share this post


Link to post
Share on other sites
How would you present all those vehicles in the editor with only an array of tags for each vehicle?

simple, by beeing able to select/deselect multiple tags at once. Unless i'm missinformed, the only thing the cfgvehicleclass contains is the display name for that class, so you lose absolutely nothing by not having inheritance, since the display name has to be overwritten in every cgfvehicleclass anyway. With tags you wouldnt even need the displayname anymore. The game could just compare the strings listed in the definition.

inheritance and the relations between vehicleClasses

there are few relations that actually make sense, so this is not a loss. For example you can have military/civilian car, military/civilian air, military/civilian structure, etc with the tag structure. You could even tag Opfor/Blufor, mod author tags (RHS, ACE, ...), Specific name tags (M16, BMP, Bradley, ...) ,subtype tags (AA, APC, MBT, ...) etc. You would have to create a gigantic tree with lots of duplicates to achieve an even remotely comparable result for little benefit.

The Priority in editor could still be retained, by using the first defined class in the array as the editor class (e.g. vehicleClasses[] = ["Structure","Military","Communication"]; -> the first one is Structure). To select one in editor you choose "Structure" from the usual dropdown menu and you will see every structure in the game in the list. To narrow it down you add tags.

When using mods that add alot of assetts with many different subvariants and camo it becomes extremely obvious that the system would need an overhaul like that. And for scripters it would be even easier... Just take the array and look for the strings you want. For ease of use it might be best to only allow lower case letters/ convert upper case to lowercase, so you dont end up with "Tank", "tank", "TANK"

Edited by X3KJ

Share this post


Link to post
Share on other sites

great topic - close to my own obsessive heart lol

shame it's wasted on BIS - as with A2, different people come along and build their expansion and DLC in a time-limited manner, with little/no QA on classnames and little/no confluence of thinking/logic...

but hell, you wouldn't get that from any commercial developer, even MS lol.

it took me almost a year to completely reshape the unsung mod with all its historical naming and factions and overlapping groups and stuff.

people still complain about parts of it now, but from a modders perspective it works really well.

one of the reasons i've not yet modded in A3 is that the configs are such a massive mess and wit han expansion pack on the horizon i really didn't feel like making the transfer yet...

good luck with this!

Share this post


Link to post
Share on other sites
...there are few relations that actually make sense, so this is not a loss.

Yeah, I can see where you're coming from. But there is certainly something lost of value, and that relation is called a set. E.g. the set of all <infantry roles> (see below).

It's the good old OO vs. loose coupling/programming against interfaces discussion all over again. And yes, OO, as in inheritance, certainly comes at a price. Composition (i.e. exactly what you suggest) usually wins for its simplicity, unless there is indeed some inherent need for the classic OO object->animal->mammal->cat dance. ;)

Btw. have you noticed how BIS came up with the availableForSupportTypes attribute?

Some examples:

config.bin/CfgVehicles/B_Mortar_01_F/availableForSupportTypes: ["Artillery"]
config.bin/CfgVehicles/O_Heli_Light_02_unarmed_F/availableForSupportTypes: ["Drop","Transport"]
config.bin/CfgVehicles/B_Heli_Attack_01_F/availableForSupportTypes: ["CAS_Heli"]
...

On the one hand that's pretty interesting, since that's the type of information/meaning we need. But - once again - it just looks so shoehorned. AvailableForSupportTypes?! Why so very specific? Couldn't a more general approach have solved many more problems too? Actually, couldn't (or rather shouldn't) a redesigned CfgVehicleClasses be used for exactly such kind of things? (And then get rid of that stupid availableForSupportTypes attribute again for needlessly littering the config?)

Either way, I think I could totally live with a vehicleClass = ["soldier", <branch>, <role>]; or something... but using these placeholders makes me wonder if tags are good enough, or if we shouldn't have some dictionary of key=value pairs? :confused:

How are you going to get a list of all <infantery roles>? Or available <branches/sections> in a faction? These sets are simply not defined with a simple tag-system, that's my problem. But I like the simplicity of it, so maybe those sets could be defined in a different place? :confused:

great topic - close to my own obsessive heart lol

Well, I'm glad this seems to pick up some more interest this time around (posting in the appropriate section of the forum might help). ;)

Share this post


Link to post
Share on other sites
But there is certainly something lost of value, and that relation is called a set. E.g. the set of all <infantry roles> (see below).

A set of all infantry is simple, because a tag is like a set. For infantry you look for all classes with a soldier tag... Looking for all grunts? use the rifleman tag. This system is 100 times more versatile and usefull then the current cfgvehicle classes could ever be.

Counter question: How do you look for all riflemen, if you would use a tree structure? You would have to browse the entire cfgvehicleclasses tree first, to filter for all different riflemen classes burried within the tree. Don't forget that you can't have a class "Soldier" inheriting from "Women" and a "Soldier" class inheriting from "Men". Everything needs unique names you end up with a big mess. Then you need to check every vehicle if it belongs to any of the rifleman types found. The tree structure doesnt allow sets in a completely satisfying manner either, so it offers no advantage whatsoever.

Remember that the structure in the tree is arbitrary, so not even the tree structure allows for easy sets the way you mention it. If it happens to be defined the wrong way around. hypothetical example: Men->Soldier->Rifleman->USArmy. You can't easily look if there are Women inside USArmy, because it's defined the wrong way around with bogus relationships.

Why do you need that set thing?

If you need it, it would be easier to put that as a layer on top of the tags. E.g. you have tags that specify what a unit is, and a set class that contains an array of tags seperately defined. This could be the cfgvehicleclasses, because those would be redundant with the tags, or cfgTagSet or something like that

class cfgVehicles {
class myNinja{
	tags[]=["Men","Soldier","Asian","Recon","SpecFor"];
};
};	

[]
class cfgVehicleclasses {  //or cfgTagSets
class MaleAsians { settags[]= ["Men","Asian"]; };
class USInfantry { settags[]= ["Soldier","US"]};
class USRifleman:USInfantry { settags[]+= ["Rifleman"]};
};

Edit: It would be better to build such things on mission build dynamically, e.g. if you want to find out what the US forces have, you look for everything with US tag, and store differing tag arrays (of tanks, of infantry, etc). Because defining it in a rigid config system is making everything super complicated and will always be purpose built - a system that contains every info for general use is impossible to achieve. Trying to force a standard on other people how to structure their things won't go well either.

Edited by X3KJ

Share this post


Link to post
Share on other sites

I'll agree with X3KJ, tags are much more useful and flexible in general to be used for the sort of thing you're suggesting. The example you've given of availableForSupportTypes is an array of "tags" anyway.

Besides, you can easily implement it via config as is. You can probably do so with both.

But as usual, standardizing it is the problem.

Share this post


Link to post
Share on other sites
Besides, you can easily implement it via config as is

for tags definitely, but the biggest immediate benefit imo (better selection in the missioneditor) would only come when BIS implements such a system. And by them doing so, they define the general structure and define the basic tags (like soldier, rifleman, ...), so the standardization problem would be reduced.

Biggest advantage in terms of development: You can have both (old cfgvehicleclasses and the tags) operative at the same time, you don't need a massive rebuild of everything at once.

Edited by X3KJ

Share this post


Link to post
Share on other sites
for tags definitely, but the biggest immediate benefit imo (better selection in the missioneditor) would only come when BIS implements such a system. And by them doing so, they define the general structure and define the basic tags (like soldier, rifleman, ...), so the standardization problem would be reduced.

Biggest advantage in terms of development: You can have both (old cfgvehicleclasses and the tags) operative at the same time, you don't need a massive rebuild of everything at once.

Yep. Hopefully 3D editor will have some improvements in that regard, "browsing" in the editor is horrible unless you know by heart where things are. But the major interest to me here with improvements to this is procedural generation.

Share this post


Link to post
Share on other sites
Yep. Hopefully 3D editor will have some improvements in that regard, "browsing" in the editor is horrible unless you know by heart where things are. But the major interest to me here with improvements to this is procedural generation.

Also something like CTRL+F, so you can cycle through all the classnames / tags assigned to them fast.

Share this post


Link to post
Share on other sites

A set of all infantry is simple, because a tag is like a set. For infantry you look for all classes with a soldier tag... Looking for all grunts? use the rifleman tag.

No. For example I want to get a set of all "infantry roles" (TL, SL, R, AR, AAR, AA, AAA, ...). If we just have one set of tags, then this is not easy to do. Hence tags should be grouped into sets - subsets even (maybe). But I agree: keeping it simple is important.

 

This system is 100 times more versatile and usefull then the current cfgvehicle classes could ever be.

Sure, pretty much anything would be better than what we currently have.

But let's not jump to conclusions, shall we? :cool:

 

How do you look for all riflemen, if you would use a tree structure?

Such a tree would be fixed/known, hence working with it would be feasible.

But I totally agree with you; what I initially proposed is stupid. :P

 

The tree structure doesnt allow sets in a completely satisfying manner either, so it offers no advantage whatsoever.

Many things can be represented with trees, but that doesn't tell us much yet (we have no circles, that's it). I like tree's to represent sets (or bundles of sets, rather) due to the simple parent->child relationship. Here, let me show you. This is what I currently propose:

lAvM8zb.png

This is a tree again. But for now, let's limit its depth to a level of 2, where we have "tag sets" at the first level. No vehicles will ever be tagged with those guys, only leaf-nodes can be used as tags. At level 2 are the actual tags, each under some "tag set".

From here, you can tag vehicles with any leaf-nodes, even multiple ones from the same tag-set if it makes sense (no need to be too strict with too many rules here, I think), just like you've proposed. E.g. ["Worker", "Asian"] for a civilian.

IMHO this is much better than a completely flat structure. I can imagine so many use cases where I want to iterate over all tags in a tag-set first. And given a tag (i.e. a leaf-node), we can easily retrieve its "meaning" by looking at the parent node, which is a tag-set (or subset, if that should be needed).

P.S. I'm not sure we really need to tag stuff with their gender (as in men/women). Those are "physical" (or intrinsic) attributes that can be easily retrieved by a quick lookup in the config. CfgVehicleClasses is not about such "physical" attributes, but about extrinsic attributes or "meaning", stuff we project onto those vehicles (just as a guideline... things are probably not always that clear though).

 

Remember that the structure in the tree is arbitrar [...]

Right. This should be much better now, no?

 

Why do you need that set thing?

There are many use cases, really. For example if you wanna build up your own dictionary (of whatever... faction-assets, or map-structures, or...), then you probably wanna iterate over all children/tags in such a tag-set. Maybe you wanna know what branches/sections (main, diver, recon, ...) or what infantry roles (SL, TL, ...) exist for a drop-down menu. Maybe you need to iterate over such a set. Plus we already have all the config-commands and functions (to access children, parents, and what not...)

Counter-example: given just the tags: ["infantry", "tl"] you really need to know (and hardcode!) all your tags in order to do something useful. But if you can retrieve the set of all "infantry" first, then it's possible to "discover" infantry roles, no need to hardcode (or know them all). Pretty much like service-registration stuff, I guess. Of course we still need to know the exact tag-sets (or services), but not really all the tags. ;)

 

If you need it, it would be easier to put that as a layer on top of the tags.

That be rather stupid IMHO. A tree is still the perfect/natural representation for such a thing, and easy to navigate/query/handle/extend...

 

It would be better to build such things on mission build dynamically [...]

Yes, that's the idea. That people can build their own little "frameworks" on top of this. Parsing, building up dictionaries and what not... in whatever way they need it.

 

But as usual, standardizing it is the problem.

It seems feasible to me. Just look at the infantry roles (TL, SL, FAC/JTAC, LAT, AT, ...). No matter if WW1, WW2, Cold War or modern/"future" era... those tags are pretty generic and have been rather stable since years. Same for civilian roles; it's not like too many would be represented in game anyways :o

Similarly vehicles roles can be defined in a rather generic way. Given we could combine tags (and attributes like mechanized/wheeled/...), we should be able to come up with something very useable (for the scope of this game anyways).

And then for structres/buildings or objects/items things are rather easy to describe too, I'd say.

 

the biggest immediate benefit imo (better selection in the missioneditor) would only come when BIS implements such a system.

That's IMHO an absolute requirement. BIS must not only introduce such a change, but also promote it, and make sure that addon-makers get the message. This is probably also a question of tooling, such that you don't end up with no tags for your new fancy addon.

 

"browsing" in the editor is horrible unless you know by heart where things are.

Good to hear! :P If this is in dire need of a redesign (I don't use the editor much), then maybe we have better chances to push for a better "back-end" in form of a redesigned CfgVehicleClasses. :cool:

And hey, maybe we/the community could even help them to (re-)tag all existing vehicles?

Or they could just hire some intern/trainee to do it, ehehe. :P

Share this post


Link to post
Share on other sites
Was this better/more clear now?

I'm afraid, I seem not to be able to serve with "short" (feel free to call me mr. wall of doom :().

Yes thank you :) Now I have something to chew on..

Share this post


Link to post
Share on other sites
Counter-example: given just the tags: ["infantry", "tl"] you really need to know (and hardcode!) all your tags in order to do something useful. But if you can retrieve the set of all "infantry" first, then it's possible to "discover" infantry roles, no need to hardcode (or know them all). Pretty much like service-registration stuff, I guess. Of course we still need to know the exact tag-sets (or services), but not really all the tags.

Why do you need to hardcode the tags? You dont. You only search for everything with "infantry", from that you pick everything with "tl" tag as well. There needs to be a naming convention, but that would need to be the case for your tree structure as well. While you can read what is inside a class you can't make sense of it. If you wanna know what infantryroles there are ("looking down") you need to know the specific name and location of the infantryrole class. Same with looking up. And for certain things there could be multiple "ups", unless you make arbitrary relationships again.

IMHO this is much better than a completely flat structure.

But it doesnt work without having the flat structure in the first place, so by arguing against a flat base structure you pull the rug from under your own feet. Otherwise you have the same mess you proposed initially, because tree = no multi inheritance -> arbitrary relationships

And hey, maybe we/the community could even help them to (re-)tag all existing vehicles?

Or they could just hire some intern/trainee to do it, ehehe.

Or you could write it yourself so they only need to do the optimizing & hardcode implementations... when it's so urgent that they MUST make such a system

Edited by X3KJ

Share this post


Link to post
Share on other sites
But it doesnt work without having the flat structure in the first place, so by arguing against a flat base structure you pull the rug from under your own feet. Otherwise you have the same mess you proposed initially, because tree = no multi inheritance -> arbitrary relationships

Nah. You seem to miss the fact that the proposed tag-sets (or tag sub-sets) are independent from each other, and that things can be tagged with tags from any tag-sets defined. And maybe I should have labeled the tag-set "Infantry" "Infantry Roles" instead. There could be other tag-sets related to infantry, plus: you do not tag things with tag-sets, only with leaf-nodes. That was the last/current proposal (tagging something infantry isn't all that helpful anyways, since we know pretty good about such "physical"/intrinsic attributes; there is no need to duplicate CfgConfig). ;)

Let's have a look at another example maybe: a module-maker wants to find all structures related to electricity on a given map, but he can't know in advance what kind of objects (addons) will be present. Thanks god things are tagged in a "meaningful" way. Having a tag set ["structure", "electricity"] would be a good start, but we can do better - similar to defining infantry roles. Because honestly, the tags "structure" and "electricity" don't carry too much meaning yet. Thus we extend the leaf-node "electricity" into a non-leaf-node (or a tag-(sub-)set)...

Now comes the "hard" part. We need to find a reasonably simple, yet powerful (enough) abstraction to describe electricity related structures. We could go with the following three tags:

  1. producer/source
  2. consumer/sink
  3. connection

Guess you can imagine how nice this would be for the maker of the next electric-grid-addon thingy. Item.

So what have we done here?

i2z0zuK.png

  • Electricity is now a tag sub-set. Objects are not supposed to be tagged with those guys, but leaf-nodes only. (It's probably best to still allow it, in case nodes get extended in the future, while things are still tagged with something that is now a tag-set)
  • A power plant can be tagged with "source" (which inherits from "electricity" and "structure"; and so is all of those guys too). But the tags that describe such a power plant can certainly also have many more tags, from any other tag-set (e.g. some leaf-nodes under "Industrial").
  • You can have structures that combine "commercial" and "cultural" tags. Whatever. I don't see the problem you still have with this approach. :(

Or you could write it yourself so they only need to do the optimizing & hardcode implementations... when it's so urgent that they MUST make such a system

Eh..., I could do what by myself now?

:confused:

The problem is not *urgent*, but it's a universal problem people are fighting with since forever. Also all those "why are there no missions for map Y" posts/worries have to do with exactly this. That is: even if you don't think this problem concerns you, it probably does anyways.

It can be fixed, but certainly not by me or anyone else on his own.

Edited by ruebe

Share this post


Link to post
Share on other sites

Much more flexibility is gained with a tags system. If you really want tag grouping, you might as well tag the tags themselves or have them have an optional set of parent tags.

If we take an example of an editor search dialog, it's a much simpler and more encompassing to describe rather than find.

Select "Structures", "Source", you get back all structures that are a "provider". You might be looking to make a small hub of utility providers. Oh you need a water cistern, remove "Structures" add, "Vehicle".

"Commercial", "Rifleman" gets you the PMC infantry.

"Civilian", "Rifleman" are rifle armed civilians

"Vehicle", "Fuel", "Sink" gets you SUV's, etc.

"Animal", "TL" gets you a wolf pack leader

The more specific your search need, the better you can describe it. And it works with procedural generation as well without having to check inheritance.

Share this post


Link to post
Share on other sites
Much more flexibility is gained with a tags system.

Maybe. But flexibility is one of many (conflicting) aspects.

Let's see how that would work out:

"Commercial", "Rifleman" gets you the PMC infantry.

"Civilian", "Rifleman" are rifle armed civilians

"Vehicle", "Fuel", "Sink" gets you SUV's, etc.

"Animal", "TL" gets you a wolf pack leader

And... you don't see a problem with this? Who is going to have the same combinatorial mindset as you do? Do you think that (all) addon-makers would come up with these combinations? And then people could also use their own/custom tags? Somehow I doubt it that I'd find many PMC infantry guys this way. :p

I honestly don't see how this could work, as nice as it may sound. If we want to end up with some kind of *standard*, BIS and addon-makers should adhere to (and that can be *reliably* parsed by anyone), then the tags that can/should be used should be well defined and clearly documented. Given some new vehicle/object, tagging it should be also standardized (to some degree). But most certainly you shouldn't get *creative* while doing so.

If you just have one huge set of tags to choose from willy-nilly, this probably isn't going to work. But if you have a well-defined bundle of tag-sets, then you can go quickly through them to determine if a tag-set applies to your vehicle/object, and if so, pick the fitting tag(s) (from a given/documented set). This should be a *no brainer*.

In case someone is missing a tag, or a tag-set even, then that's a feature request and can be introduced if deemed to be useful enough. Then that tag or tag-set can be documented, such that people will know about it. But honestly, I don't think that there would be too many such requests, once the basics are defined (and a good level of abstraction has been found). Well, who knows...

Re: It's a universal problem

Citation needed, right? Right!

So, lemme see what I've found just with a quick search in some popular missions/addons:

  • DAC, DAC_Config_Units.sqf:
    switch (_TypNumber) do
    {
    //-------------------------------------------------------------------------------------------------
    // REDFOR (A3)
     case 0:
     {
       _Unit_Pool_S = ["O_crew_F","O_Helipilot_F","O_Soldier_SL_F","O_soldier_AR_F","O_soldier_AR_F","O_soldier_exp_F","O_soldier_GL_F","O_soldier_GL_F","O_soldier_M_F","O_medic_F","O_soldier_AA_F","O_soldier_repair_F","O_Soldier_F","O_Soldier_F","O_soldier_LAT_F","O_soldier_LAT_F","O_soldier_lite_F","O_soldier_TL_F","O_soldier_TL_F"];
       _Unit_Pool_V = ["O_MRAP_02_F","O_MRAP_02_gmg_F","O_MRAP_02_hmg_F"];
       _Unit_Pool_T = ["O_MBT_02_arty_F","I_APC_Wheeled_03_cannon_F","O_APC_Tracked_02_cannon_F","O_APC_Wheeled_02_rcws_F","O_MBT_02_cannon_F","O_APC_Tracked_02_AA_F"];
    _Unit_Pool_A = ["O_Heli_Attack_02_F","O_Heli_Light_02_F","O_Heli_Light_02_armed_F"];
     };
    //-------------------------------------------------------------------------------------------------
    // BLUFOR (A3)
     case 1:
     {
       _Unit_Pool_S = ["B_crew_F","B_Helipilot_F","B_Soldier_SL_F","B_soldier_AR_F","B_soldier_AR_F","B_soldier_exp_F","B_soldier_GL_F","B_soldier_GL_F","B_soldier_AA_F","B_soldier_M_F","B_medic_F","B_soldier_repair_F","B_Soldier_F","B_Soldier_F","B_soldier_LAT_F","B_soldier_LAT_F","B_soldier_lite_F","B_soldier_TL_F","B_soldier_TL_F"];
       _Unit_Pool_V = ["B_MRAP_01_F","B_MRAP_01_gmg_F","B_MRAP_01_hmg_F"];
       _Unit_Pool_T = ["B_APC_Wheeled_01_cannon_F","B_APC_Tracked_01_AA_F","B_APC_Tracked_01_rcws_F","B_MBT_01_cannon_F","B_MBT_01_arty_F","B_MBT_01_mlrs_F"];
       _Unit_Pool_A = ["B_Heli_Light_01_armed_F","B_Heli_Transport_01_camo_F","B_Heli_Light_01_F"];
     };
    

  • M.E.R.C.S., spawnMenGroup.sqf:
    _arrays = [];
    switch (_side) do{
    case west:{
    	_BLUmenSTD = ["B_Soldier_A_F","B_soldier_AR_F","B_medic_F","B_engineer_F","B_soldier_exp_F","B_Soldier_GL_F","B_soldier_M_F","B_soldier_AA_F","B_soldier_AT_F","B_officer_F","B_soldier_repair_F","B_Soldier_F","B_soldier_LAT_F","B_Soldier_lite_F","B_Soldier_SL_F","B_Soldier_TL_F","B_soldier_AAR_F","B_soldier_AAA_F","B_soldier_AAT_F","B_soldier_AAR_F","B_soldier_AAA_F","B_soldier_AAT_F"];
    	_BLUmenSF = ["B_recon_exp_F","B_recon_JTAC_F","B_recon_M_F","B_recon_medic_F","B_recon_F","B_recon_LAT_F","B_recon_TL_F"];
    	_BLUmenGUE = ["B_G_Soldier_A_F","B_G_soldier_AR_F","B_G_medic_F","B_G_engineer_F","B_G_soldier_exp_F","B_G_Soldier_GL_F","B_G_soldier_M_F","B_G_officer_F","B_G_Soldier_F","B_G_soldier_LAT_F","B_G_Soldier_lite_F","B_G_Soldier_SL_F","B_G_Soldier_TL_F"];
    
    	if ("STD" in _selection) then {_arrays set [(count _arrays), _BLUmenSTD]};
    	if ("SF" in _selection) then {_arrays set [(count _arrays), _BLUmenSF]};
    	if ("GUE" in _selection) then {_arrays set [(count _arrays), _BLUmenGUE]};
    };
    
    case east:{
    	_OPFmenSTD = ["O_Soldier_A_F","O_soldier_AR_F","O_medic_F","O_engineer_F","O_soldier_exp_F","O_Soldier_GL_F","O_soldier_M_F","O_soldier_AA_F","O_soldier_AT_F","O_officer_F","O_soldier_repair_F","O_Soldier_F","O_soldier_LAT_F","O_Soldier_lite_F","O_Soldier_SL_F","O_Soldier_TL_F","O_soldier_AAR_F","O_soldier_AAA_F","O_soldier_AAT_F"];
    	_OPFmenSF = ["O_recon_exp_F","O_recon_JTAC_F","O_recon_M_F","O_recon_medic_F","O_recon_F","O_recon_LAT_F","O_recon_TL_F","O_soldier_AAR_F","O_soldier_AAA_F","O_soldier_AAT_F"];
    	_OPFmenGUE = ["O_G_Soldier_A_F","O_G_soldier_AR_F","O_G_medic_F","O_G_engineer_F","O_G_soldier_exp_F","O_G_Soldier_GL_F","O_G_soldier_M_F","O_G_officer_F","O_G_Soldier_F","O_G_soldier_LAT_F","O_G_Soldier_lite_F","O_G_Soldier_SL_F","O_G_Soldier_TL_F"];
    
    	if ("STD" in _selection) then {_arrays set [(count _arrays), _OPFmenSTD]};
    	if ("SF" in _selection) then {_arrays set [(count _arrays), _OPFmenSF]};
    	if ("GUE" in _selection) then {_arrays set [(count _arrays), _OPFmenGUE]};
    };
    

  • ALiVE, staticData.sqf (this one is great! bwaahahahaha :()
    ALIVE_CQBStrategicTypes =
    [
    //A3
    "Land_Cargo_Patrol_V1_F",
    "Land_Cargo_Patrol_V2_F",
    "Land_Cargo_House_V1_F",
    "Land_Cargo_House_V2_F",
    "Land_Cargo_Tower_V3_F",
    "Land_Airport_Tower_F",
    "Land_Cargo_HQ_V1_F",
    "Land_Cargo_HQ_V2_F",
    "Land_MilOffices_V1_F",
    "Land_Offices_01_V1_F",
    "Land_Research_HQ_F",
    ...
    ];
    
    ...
    
    /*
    * Custom support and ammo classes for faction
    * Used by MP CP to place support vehicles and ammo boxes
    * If no faction specific settings are found will fall back to side
    */
    
    
    ALIVE_sideDefaultSupports = [] call ALIVE_fnc_hashCreate;
    [ALIVE_sideDefaultSupports, "EAST", ["O_Truck_02_Ammo_F","O_Truck_02_box_F","O_Truck_02_fuel_F","O_Truck_02_medical_F"]] call ALIVE_fnc_hashSet; // ,"Box_East_AmmoVeh_F"
    [ALIVE_sideDefaultSupports, "WEST", ["B_Truck_01_ammo_F","B_Truck_01_fuel_F","B_Truck_01_medical_F","B_Truck_01_Repair_F"]] call ALIVE_fnc_hashSet; // ,"Box_IND_AmmoVeh_F"
    [ALIVE_sideDefaultSupports, "GUER", ["I_Truck_02_ammo_F","I_Truck_02_box_F","I_Truck_02_fuel_F","I_Truck_02_medical_F"]] call ALIVE_fnc_hashSet;
    [ALIVE_sideDefaultSupports, "CIV", ["C_Van_01_box_F","C_Van_01_transport_F","C_Van_01_fuel_F"]] call ALIVE_fnc_hashSet;
    
    ...
    
    ALIVE_airBuildingTypes = [];
    ALIVE_militaryParkingBuildingTypes = [];
    ALIVE_militarySupplyBuildingTypes = [];
    ALIVE_militaryHQBuildingTypes = [];
    ALIVE_militaryAirBuildingTypes = [];
    ALIVE_civilianAirBuildingTypes = [];
    ALIVE_militaryHeliBuildingTypes = [];
    ALIVE_civilianHeliBuildingTypes = [];
    ALIVE_militaryBuildingTypes = [];
    
    ALIVE_civilianPopulationBuildingTypes = [];
    ALIVE_civilianHQBuildingTypes = [];
    ALIVE_civilianPowerBuildingTypes = [];
    ALIVE_civilianCommsBuildingTypes = [];
    ALIVE_civilianMarineBuildingTypes = [];
    ALIVE_civilianRailBuildingTypes = [];
    ALIVE_civilianFuelBuildingTypes = [];
    ALIVE_civilianConstructionBuildingTypes = [];
    ALIVE_civilianSettlementBuildingTypes = [];
    
    // Altis Stratis
    if(_worldName == "Altis" || _worldName == "Stratis" || _worldName == "Koplic") then {
    
       ALIVE_airBuildingTypes = ALIVE_airBuildingTypes + [
       	"hangar"
       ];
    
       ALIVE_militaryParkingBuildingTypes = ALIVE_militaryParkingBuildingTypes + [
       	"bunker",
       	"cargo_house_v",
       	"cargo_patrol_",
       	"research"
       ];
    
       ALIVE_militarySupplyBuildingTypes = ALIVE_militarySupplyBuildingTypes + [
       	"barrack",
       	"cargo_hq_",
       	"miloffices",
       	"cargo_house_v",
       	"cargo_patrol_",
       	"research"
       ];
    
       ...
    };
    


    ...and so on, and so forth...
    Come on now. This is just sad and needs to stop. :(

  • TPW, tpw_core.sqf:
    // HABITABLE HOUSES
    tpw_core_habitable = [ // Habitable Greek houses with white walls, red roofs, intact doors and windows
    "Land_i_House_Small_01_V1_F",
    "Land_i_House_Small_01_V2_F",
    "Land_i_House_Small_01_V3_F",
    "Land_i_House_Small_02_V1_F",
    "Land_i_House_Small_02_V2_F",
    "Land_i_House_Small_02_V3_F",
    "Land_i_House_Small_03_V1_F",
    ...
    
    

  • Pilgrimage, JRInit.sqf:
    RYD_JR_BetterLootBuildings = 
    [
    "Land_BagBunker_Large_F",
    "Land_BagBunker_Small_F",
    "Land_BagBunker_Tower_F",
    "Land_Barracks_ruins_F",
    "Land_i_Barracks_V1_F",
    "Land_i_Barracks_V1_dam_F",
    "Land_i_Barracks_V2_F",
    "Land_i_Barracks_V2_dam_F",
    "Land_u_Barracks_V2_F",
    ...
    ];
    

  • HETMAN - Artificial Leader, RHQLibrary.sqf:
    RYD_WS_recon_class = 
    [
    "o_recon_exp_f",
    "o_recon_f",
    "o_recon_jtac_f",
    "o_recon_lat_f",
    "o_recon_m_f",
    "o_recon_medic_f",
    ...
       ];
    
    RYD_WS_FO_class =
    [
    "i_spotter_f",
    "o_spotter_f",
    "b_spotter_f",
    "o_recon_jtac_f",
    "b_recon_jtac_f"
    ];
    
    RYD_WS_snipers_class = 
    [
    "i_sniper_f",
    "o_sniper_f",
    "b_sniper_f",
    "i_soldier_m_f",
    ...
    ];
    
    ...
    
    RYD_WS_Art_class = 
    [
    "b_mbt_01_arty_f",
    "o_mbt_02_arty_f",
    "b_mbt_01_mlrs_f",
    "i_mortar_01_f",
    "o_mortar_01_f",
    "b_g_mortar_01_f",
    "b_mortar_01_f"
    ];
    
    RYD_WS_HArmor_class = 
    [
    "b_mbt_01_cannon_f",
    "b_mbt_01_tusk_f",
    "o_mbt_02_cannon_f",
    "i_mbt_03_cannon_f"
    ];
    
    RYD_WS_MArmor_class = 
    [
    ];
    
    RYD_WS_LArmor_class = 
    [
    "i_apc_wheeled_03_cannon_f",
    "o_apc_tracked_02_aa_f",
    "o_apc_tracked_02_cannon_f",
    "o_apc_wheeled_02_rcws_f",
    "b_apc_tracked_01_aa_f",
    "b_apc_tracked_01_rcws_f",
    "b_apc_wheeled_01_cannon_f",
    "i_apc_tracked_03_cannon_f"
    ];
    
    RYD_WS_LArmorAT_class =
    [
    "b_apc_wheeled_01_cannon_f",
    "i_apc_wheeled_03_cannon_f",
    "o_apc_tracked_02_cannon_f",
    "i_apc_tracked_03_cannon_f"
    ];
    
    RYD_WS_Cars_class =
    [
    "i_mrap_03_f",
    "i_mrap_03_gmg_f",
    "i_mrap_03_hmg_f",
    "i_quadbike_01_f",
    ...
    ];
    
    ...
    
    RYD_WS_rep =
    [
    "o_truck_03_repair_f",
    "i_truck_02_box_f",
    "o_truck_02_box_f",
    "b_apc_tracked_01_crv_f",
    "b_truck_01_repair_f",
    "b_g_offroad_01_repair_f",
    "o_heli_transport_04_repair_f"
    ];
    
    RYD_WS_med = 
    [
    "o_truck_03_medical_f",
    "i_truck_02_medical_f",
    "o_truck_02_medical_f",
    "b_truck_01_medical_f",
    "o_heli_transport_04_medevac_f"
    ];
    
    RYD_WS_fuel =
    [
    "o_truck_03_fuel_f",
    "i_truck_02_fuel_f",
    "o_truck_02_fuel_f",
    ...
    ];
    


    ...and so on, and so on. Another really good one!
    Wait, you missed the best part! It goes on with A2 classes too (because Addons, yeah!):

    RHQ_specFor_A2 = 
    [
    "rus_soldier_sab",
    "rus_soldier_gl",
    "rus_soldier_marksman",
    "rus_commander",
    "rus_soldier1",
    "rus_soldier2",
    "rus_soldier3",
    "rus_soldier_tl"
    ];
    
    RHQ_recon_A2 =
    [
    "fr_tl",
    "fr_sykes",
    "fr_r",
    "fr_rodriguez",
    "fr_ohara",
    "fr_miles",
    ...
    ];
    
    ...
    
    RHQ_ATinf_A2 = 
    [
    "usmc_soldier_hat",
    "usmc_soldier_at",
    "usmc_soldier_lat",
    "hmmwv_tow",
    "cdf_soldier_rpg",
    "ru_soldier_hat",
    "ru_soldier_at",
    "ru_soldier_lat",
    "mvd_soldier_at",
    "ins_soldier_at",
    "gue_soldier_at"
    ];
    
    RHQ_AAinf_A2 = 
    [
    "usmc_soldier_aa",
    "hmmwv_avenger",
    "cdf_soldier_strela",
    ...
    ];
    


    ...and so on... D:

  • Karma Modules, karma_site_side_func.sqf:
    if (_roadblockside == "NATO") then {
    //hint "Side Check Is Working";
    _centerside = WEST;
    _unittype = ["B_Soldier_F", "B_soldier_AR_F", "B_soldier_LAT_F", "B_Soldier_GL_F"];
    _unit1type = _unittype call BIS_fnc_selectRandom;
    _unit2type = _unittype call BIS_fnc_selectRandom;
    _unit3type = _unittype call BIS_fnc_selectRandom;
    };	
    if (_roadblockside == "AAF") then {
    //hint "Side Check Is Working";
    _centerside = RESISTANCE;
    _unittype = ["I_Soldier_F", "I_soldier_AR_F", "I_soldier_LAT_F", "I_Soldier_GL_F"];
    _unit1type = _unittype call BIS_fnc_selectRandom;
    _unit2type = _unittype call BIS_fnc_selectRandom;
    _unit3type = _unittype call BIS_fnc_selectRandom;
    };
    ...
    

  • Dynamic Whole Map ArmA3 Missions by SaOk, ConstructFuncs.sqf:
    if (_class in ["Land_TentA_F","Land_CampingChair_V1_F","Land_Cargo_House_V1_F","Land_dp_smallTank_F","Land_dp_smallFactory_F","Land_dp_mainFactory_F","Land_MilOffices_V1_F","Land_Radar_Small_F","Land_Radar_F","Land_TTowerBig_2_F","Land_TTowerBig_1_F","Land_Pallet_F","Land_Scaffolding_F","Land_Shoot_House_Wall_Long_F","Land_Mil_WallBig_4m_F","Land_Mil_WiredFence_F","Land_PowerGenerator_F","Land_PortableLight_double_F","Land_PortableLight_single_F","Land_FieldToilet_F","Land_Sink_F","Land_CampingTable_F","Land_Camping_Light_F","Land_WoodenTable_small_F","Land_ShelvesWooden_F","Land_TableDesk_F","Land_ChairPlastic_F","MapBoard_altis_F","Land_TBox_F","Land_TTowerSmall_1_F","Land_CncWall4_F","Land_LampHalogen_F","Box_IND_Wps_F","Land_HelipadSquare_F","FirePlace_burning_F","Land_TentDome_F","Land_HBarrierWall4_F","CamoNet_BLUFOR_F","CamoNet_BLUFOR_open_F","CamoNet_BLUFOR_big_F","Land_BarrelWater_F","Land_BagFence_Long_F","Land_BagFence_Round_F","Land_HBarrier_3_F","Land_HBarrier_5_F","Land_HBarrierBig_F","Land_Razorwire_F","Land_Crash_barrier_F","Land_BarGate_F"]) then {
    if (pisteet >= _cost && {isNil{_post getvariable "StaticO"} || {count (_post getvariable "StaticO") < 78} || {!GUARDLIM}}) then {
    _veh setvariable ["Ghost",nil];
    _veh setvariable ["AmCrate",1];
    if !(_class in ["FirePlace_burning_F"]) then {[_veh,0] SPAWN VehLife;};
    _nul = [-_cost, "Construction",side player] SPAWN PRESTIGECHANGE;
    pisteet = pisteet - _cost;
    if (_class in ["Land_TentDome_F","Land_TentA_F"]) then {
    _post = ([(getposATL _veh)] CALL RETURNGUARDPOST);
    _post setvariable ["CampV",1];
    //(_post getvariable "Gmark") setMarkerText " Guardpost with tent(s)";
    };
    
    _post = ([(getposATL _veh)] CALL RETURNGUARDPOST);
    if !(_class in ["Land_Cargo_House_V1_F","Land_dp_smallTank_F","Land_dp_smallFactory_F","Land_dp_mainFactory_F","Land_MilOffices_V1_F","Land_Radar_Small_F","Land_Radar_F","Land_TTowerBig_2_F","Land_TTowerBig_1_F"]) then {
    _earlier = _post getvariable "StaticO";
    _id = "N"+(format["%1",count _earlier]);
    _post setvariable ["StaticO",_earlier + [[_class,getposATL _veh, direction _veh, (surfaceNormal (getposATL _veh)),_id]]];
    } else {
    _earlier = if (!isNil{_post getvariable "StaticOS"}) then {_post getvariable "StaticOS"} else {[]};
    _id = "NS"+(format["%1",count _earlier]);
    _post setvariable ["StaticOS",_earlier + [[_class,getposATL _veh, direction _veh, (surfaceNormal (getposATL _veh)),_id]]];
    if (_class == "Land_dp_mainFactory_F") then {[getposATL _veh,"Fac"] CALL SAOKCREATESTPOINT;};
    if (_class in ["Land_dp_smallFactory_F","Land_dp_smallTank_F"]) then {[getposATL _veh,"Sto"] CALL SAOKCREATESTPOINT;};
    if (_class == "Land_MilOffices_V1_F") then {"MilOff" CALL SAOKADDPROG;};
    if (_class == "Land_Radar_Small_F") then {"RadarS" CALL SAOKADDPROG;};
    if (_class == "Land_Radar_F") then {"Radar" CALL SAOKADDPROG;};
    if (_class == "Land_TTowerBig_2_F") then {"MilTower" CALL SAOKADDPROG;};
    if (_class == "Land_TTowerBig_1_F") then {"MilTower" CALL SAOKADDPROG;};
    ...
    


    ^^ Very interesting, isn't it?
    Too bad he has to hardcode classnames to do such a thing... :(

  • ...and so on, and many more. And each one of those guys has to maintain these various lists by hand; or new things simply won't work. Have fun porting such things to a new map, or integrating new factions and such stuff... All those hours of precious manpower lost, just because CfgVehicleClasses is a joke. All those awesome ideas never carried out, because they were deemed to be infeasible. All those missions or factions and other toys never played with, say on the latest fancy map that just got out.
    It's depressing. :(

^^ Fixing this for sure could have a leverage effect on the whole arma ecosystem. :cool:

Share this post


Link to post
Share on other sites
Maybe. But flexibility is one of many (conflicting) aspects.

Let's see how that would work out:

And... you don't see a problem with this? Who is going to have the same combinatorial mindset as you do? Do you think that (all) addon-makers would come up with these combinations? And then people could also use their own/custom tags? Somehow I doubt it that I'd find many PMC infantry guys this way. :p

I honestly don't see how this could work, as nice as it may sound. If we want to end up with some kind of *standard*, BIS and addon-makers should adhere to (and that can be *reliably* parsed by anyone), then the tags that can/should be used should be well defined and clearly documented. Given some new vehicle/object, tagging it should be also standardized (to some degree). But most certainly you shouldn't get *creative* while doing so.

If you just have one huge set of tags to choose from willy-nilly, this probably isn't going to work. But if you have a well-defined bundle of tag-sets, then you can go quickly through them to determine if a tag-set applies to your vehicle/object, and if so, pick the fitting tag(s) (from a given/documented set). This should be a *no brainer*.

In case someone is missing a tag, or a tag-set even, then that's a feature request and can be introduced if deemed to be useful enough. Then that tag or tag-set can be documented, such that people will know about it. But honestly, I don't think that there would be too many such requests, once the basics are defined (and a good level of abstraction has been found). Well, who knows...

Re: It's a universal problem

Citation needed, right? Right!

So, lemme see what I've found just with a quick search in some popular missions/addons:

  • DAC, DAC_Config_Units.sqf:
    switch (_TypNumber) do
    {
    //-------------------------------------------------------------------------------------------------
    // REDFOR (A3)
     case 0:
     {
       _Unit_Pool_S = ["O_crew_F","O_Helipilot_F","O_Soldier_SL_F","O_soldier_AR_F","O_soldier_AR_F","O_soldier_exp_F","O_soldier_GL_F","O_soldier_GL_F","O_soldier_M_F","O_medic_F","O_soldier_AA_F","O_soldier_repair_F","O_Soldier_F","O_Soldier_F","O_soldier_LAT_F","O_soldier_LAT_F","O_soldier_lite_F","O_soldier_TL_F","O_soldier_TL_F"];
       _Unit_Pool_V = ["O_MRAP_02_F","O_MRAP_02_gmg_F","O_MRAP_02_hmg_F"];
       _Unit_Pool_T = ["O_MBT_02_arty_F","I_APC_Wheeled_03_cannon_F","O_APC_Tracked_02_cannon_F","O_APC_Wheeled_02_rcws_F","O_MBT_02_cannon_F","O_APC_Tracked_02_AA_F"];
    _Unit_Pool_A = ["O_Heli_Attack_02_F","O_Heli_Light_02_F","O_Heli_Light_02_armed_F"];
     };
    //-------------------------------------------------------------------------------------------------
    // BLUFOR (A3)
     case 1:
     {
       _Unit_Pool_S = ["B_crew_F","B_Helipilot_F","B_Soldier_SL_F","B_soldier_AR_F","B_soldier_AR_F","B_soldier_exp_F","B_soldier_GL_F","B_soldier_GL_F","B_soldier_AA_F","B_soldier_M_F","B_medic_F","B_soldier_repair_F","B_Soldier_F","B_Soldier_F","B_soldier_LAT_F","B_soldier_LAT_F","B_soldier_lite_F","B_soldier_TL_F","B_soldier_TL_F"];
       _Unit_Pool_V = ["B_MRAP_01_F","B_MRAP_01_gmg_F","B_MRAP_01_hmg_F"];
       _Unit_Pool_T = ["B_APC_Wheeled_01_cannon_F","B_APC_Tracked_01_AA_F","B_APC_Tracked_01_rcws_F","B_MBT_01_cannon_F","B_MBT_01_arty_F","B_MBT_01_mlrs_F"];
       _Unit_Pool_A = ["B_Heli_Light_01_armed_F","B_Heli_Transport_01_camo_F","B_Heli_Light_01_F"];
     };
    

  • M.E.R.C.S., spawnMenGroup.sqf:
    _arrays = [];
    switch (_side) do{
    case west:{
    	_BLUmenSTD = ["B_Soldier_A_F","B_soldier_AR_F","B_medic_F","B_engineer_F","B_soldier_exp_F","B_Soldier_GL_F","B_soldier_M_F","B_soldier_AA_F","B_soldier_AT_F","B_officer_F","B_soldier_repair_F","B_Soldier_F","B_soldier_LAT_F","B_Soldier_lite_F","B_Soldier_SL_F","B_Soldier_TL_F","B_soldier_AAR_F","B_soldier_AAA_F","B_soldier_AAT_F","B_soldier_AAR_F","B_soldier_AAA_F","B_soldier_AAT_F"];
    	_BLUmenSF = ["B_recon_exp_F","B_recon_JTAC_F","B_recon_M_F","B_recon_medic_F","B_recon_F","B_recon_LAT_F","B_recon_TL_F"];
    	_BLUmenGUE = ["B_G_Soldier_A_F","B_G_soldier_AR_F","B_G_medic_F","B_G_engineer_F","B_G_soldier_exp_F","B_G_Soldier_GL_F","B_G_soldier_M_F","B_G_officer_F","B_G_Soldier_F","B_G_soldier_LAT_F","B_G_Soldier_lite_F","B_G_Soldier_SL_F","B_G_Soldier_TL_F"];
    
    	if ("STD" in _selection) then {_arrays set [(count _arrays), _BLUmenSTD]};
    	if ("SF" in _selection) then {_arrays set [(count _arrays), _BLUmenSF]};
    	if ("GUE" in _selection) then {_arrays set [(count _arrays), _BLUmenGUE]};
    };
    
    case east:{
    	_OPFmenSTD = ["O_Soldier_A_F","O_soldier_AR_F","O_medic_F","O_engineer_F","O_soldier_exp_F","O_Soldier_GL_F","O_soldier_M_F","O_soldier_AA_F","O_soldier_AT_F","O_officer_F","O_soldier_repair_F","O_Soldier_F","O_soldier_LAT_F","O_Soldier_lite_F","O_Soldier_SL_F","O_Soldier_TL_F","O_soldier_AAR_F","O_soldier_AAA_F","O_soldier_AAT_F"];
    	_OPFmenSF = ["O_recon_exp_F","O_recon_JTAC_F","O_recon_M_F","O_recon_medic_F","O_recon_F","O_recon_LAT_F","O_recon_TL_F","O_soldier_AAR_F","O_soldier_AAA_F","O_soldier_AAT_F"];
    	_OPFmenGUE = ["O_G_Soldier_A_F","O_G_soldier_AR_F","O_G_medic_F","O_G_engineer_F","O_G_soldier_exp_F","O_G_Soldier_GL_F","O_G_soldier_M_F","O_G_officer_F","O_G_Soldier_F","O_G_soldier_LAT_F","O_G_Soldier_lite_F","O_G_Soldier_SL_F","O_G_Soldier_TL_F"];
    
    	if ("STD" in _selection) then {_arrays set [(count _arrays), _OPFmenSTD]};
    	if ("SF" in _selection) then {_arrays set [(count _arrays), _OPFmenSF]};
    	if ("GUE" in _selection) then {_arrays set [(count _arrays), _OPFmenGUE]};
    };
    

  • ALiVE, staticData.sqf (this one is great! bwaahahahaha :()
    ALIVE_CQBStrategicTypes =
    [
    //A3
    "Land_Cargo_Patrol_V1_F",
    "Land_Cargo_Patrol_V2_F",
    "Land_Cargo_House_V1_F",
    "Land_Cargo_House_V2_F",
    "Land_Cargo_Tower_V3_F",
    "Land_Airport_Tower_F",
    "Land_Cargo_HQ_V1_F",
    "Land_Cargo_HQ_V2_F",
    "Land_MilOffices_V1_F",
    "Land_Offices_01_V1_F",
    "Land_Research_HQ_F",
    ...
    ];
    
    ...
    
    /*
    * Custom support and ammo classes for faction
    * Used by MP CP to place support vehicles and ammo boxes
    * If no faction specific settings are found will fall back to side
    */
    
    
    ALIVE_sideDefaultSupports = [] call ALIVE_fnc_hashCreate;
    [ALIVE_sideDefaultSupports, "EAST", ["O_Truck_02_Ammo_F","O_Truck_02_box_F","O_Truck_02_fuel_F","O_Truck_02_medical_F"]] call ALIVE_fnc_hashSet; // ,"Box_East_AmmoVeh_F"
    [ALIVE_sideDefaultSupports, "WEST", ["B_Truck_01_ammo_F","B_Truck_01_fuel_F","B_Truck_01_medical_F","B_Truck_01_Repair_F"]] call ALIVE_fnc_hashSet; // ,"Box_IND_AmmoVeh_F"
    [ALIVE_sideDefaultSupports, "GUER", ["I_Truck_02_ammo_F","I_Truck_02_box_F","I_Truck_02_fuel_F","I_Truck_02_medical_F"]] call ALIVE_fnc_hashSet;
    [ALIVE_sideDefaultSupports, "CIV", ["C_Van_01_box_F","C_Van_01_transport_F","C_Van_01_fuel_F"]] call ALIVE_fnc_hashSet;
    
    ...
    
    ALIVE_airBuildingTypes = [];
    ALIVE_militaryParkingBuildingTypes = [];
    ALIVE_militarySupplyBuildingTypes = [];
    ALIVE_militaryHQBuildingTypes = [];
    ALIVE_militaryAirBuildingTypes = [];
    ALIVE_civilianAirBuildingTypes = [];
    ALIVE_militaryHeliBuildingTypes = [];
    ALIVE_civilianHeliBuildingTypes = [];
    ALIVE_militaryBuildingTypes = [];
    
    ALIVE_civilianPopulationBuildingTypes = [];
    ALIVE_civilianHQBuildingTypes = [];
    ALIVE_civilianPowerBuildingTypes = [];
    ALIVE_civilianCommsBuildingTypes = [];
    ALIVE_civilianMarineBuildingTypes = [];
    ALIVE_civilianRailBuildingTypes = [];
    ALIVE_civilianFuelBuildingTypes = [];
    ALIVE_civilianConstructionBuildingTypes = [];
    ALIVE_civilianSettlementBuildingTypes = [];
    
    // Altis Stratis
    if(_worldName == "Altis" || _worldName == "Stratis" || _worldName == "Koplic") then {
    
       ALIVE_airBuildingTypes = ALIVE_airBuildingTypes + [
       	"hangar"
       ];
    
       ALIVE_militaryParkingBuildingTypes = ALIVE_militaryParkingBuildingTypes + [
       	"bunker",
       	"cargo_house_v",
       	"cargo_patrol_",
       	"research"
       ];
    
       ALIVE_militarySupplyBuildingTypes = ALIVE_militarySupplyBuildingTypes + [
       	"barrack",
       	"cargo_hq_",
       	"miloffices",
       	"cargo_house_v",
       	"cargo_patrol_",
       	"research"
       ];
    
       ...
    };
    


    ...and so on, and so forth...
    Come on now. This is just sad and needs to stop. :(

  • TPW, tpw_core.sqf:
    // HABITABLE HOUSES
    tpw_core_habitable = [ // Habitable Greek houses with white walls, red roofs, intact doors and windows
    "Land_i_House_Small_01_V1_F",
    "Land_i_House_Small_01_V2_F",
    "Land_i_House_Small_01_V3_F",
    "Land_i_House_Small_02_V1_F",
    "Land_i_House_Small_02_V2_F",
    "Land_i_House_Small_02_V3_F",
    "Land_i_House_Small_03_V1_F",
    ...
    
    

  • Pilgrimage, JRInit.sqf:
    RYD_JR_BetterLootBuildings = 
    [
    "Land_BagBunker_Large_F",
    "Land_BagBunker_Small_F",
    "Land_BagBunker_Tower_F",
    "Land_Barracks_ruins_F",
    "Land_i_Barracks_V1_F",
    "Land_i_Barracks_V1_dam_F",
    "Land_i_Barracks_V2_F",
    "Land_i_Barracks_V2_dam_F",
    "Land_u_Barracks_V2_F",
    ...
    ];
    

  • HETMAN - Artificial Leader, RHQLibrary.sqf:
    RYD_WS_recon_class = 
    [
    "o_recon_exp_f",
    "o_recon_f",
    "o_recon_jtac_f",
    "o_recon_lat_f",
    "o_recon_m_f",
    "o_recon_medic_f",
    ...
       ];
    
    RYD_WS_FO_class =
    [
    "i_spotter_f",
    "o_spotter_f",
    "b_spotter_f",
    "o_recon_jtac_f",
    "b_recon_jtac_f"
    ];
    
    RYD_WS_snipers_class = 
    [
    "i_sniper_f",
    "o_sniper_f",
    "b_sniper_f",
    "i_soldier_m_f",
    ...
    ];
    
    ...
    
    RYD_WS_Art_class = 
    [
    "b_mbt_01_arty_f",
    "o_mbt_02_arty_f",
    "b_mbt_01_mlrs_f",
    "i_mortar_01_f",
    "o_mortar_01_f",
    "b_g_mortar_01_f",
    "b_mortar_01_f"
    ];
    
    RYD_WS_HArmor_class = 
    [
    "b_mbt_01_cannon_f",
    "b_mbt_01_tusk_f",
    "o_mbt_02_cannon_f",
    "i_mbt_03_cannon_f"
    ];
    
    RYD_WS_MArmor_class = 
    [
    ];
    
    RYD_WS_LArmor_class = 
    [
    "i_apc_wheeled_03_cannon_f",
    "o_apc_tracked_02_aa_f",
    "o_apc_tracked_02_cannon_f",
    "o_apc_wheeled_02_rcws_f",
    "b_apc_tracked_01_aa_f",
    "b_apc_tracked_01_rcws_f",
    "b_apc_wheeled_01_cannon_f",
    "i_apc_tracked_03_cannon_f"
    ];
    
    RYD_WS_LArmorAT_class =
    [
    "b_apc_wheeled_01_cannon_f",
    "i_apc_wheeled_03_cannon_f",
    "o_apc_tracked_02_cannon_f",
    "i_apc_tracked_03_cannon_f"
    ];
    
    RYD_WS_Cars_class =
    [
    "i_mrap_03_f",
    "i_mrap_03_gmg_f",
    "i_mrap_03_hmg_f",
    "i_quadbike_01_f",
    ...
    ];
    
    ...
    
    RYD_WS_rep =
    [
    "o_truck_03_repair_f",
    "i_truck_02_box_f",
    "o_truck_02_box_f",
    "b_apc_tracked_01_crv_f",
    "b_truck_01_repair_f",
    "b_g_offroad_01_repair_f",
    "o_heli_transport_04_repair_f"
    ];
    
    RYD_WS_med = 
    [
    "o_truck_03_medical_f",
    "i_truck_02_medical_f",
    "o_truck_02_medical_f",
    "b_truck_01_medical_f",
    "o_heli_transport_04_medevac_f"
    ];
    
    RYD_WS_fuel =
    [
    "o_truck_03_fuel_f",
    "i_truck_02_fuel_f",
    "o_truck_02_fuel_f",
    ...
    ];
    


    ...and so on, and so on. Another really good one!
    Wait, you missed the best part! It goes on with A2 classes too (because Addons, yeah!):

    RHQ_specFor_A2 = 
    [
    "rus_soldier_sab",
    "rus_soldier_gl",
    "rus_soldier_marksman",
    "rus_commander",
    "rus_soldier1",
    "rus_soldier2",
    "rus_soldier3",
    "rus_soldier_tl"
    ];
    
    RHQ_recon_A2 =
    [
    "fr_tl",
    "fr_sykes",
    "fr_r",
    "fr_rodriguez",
    "fr_ohara",
    "fr_miles",
    ...
    ];
    
    ...
    
    RHQ_ATinf_A2 = 
    [
    "usmc_soldier_hat",
    "usmc_soldier_at",
    "usmc_soldier_lat",
    "hmmwv_tow",
    "cdf_soldier_rpg",
    "ru_soldier_hat",
    "ru_soldier_at",
    "ru_soldier_lat",
    "mvd_soldier_at",
    "ins_soldier_at",
    "gue_soldier_at"
    ];
    
    RHQ_AAinf_A2 = 
    [
    "usmc_soldier_aa",
    "hmmwv_avenger",
    "cdf_soldier_strela",
    ...
    ];
    


    ...and so on... D:

  • Karma Modules, karma_site_side_func.sqf:
    if (_roadblockside == "NATO") then {
    //hint "Side Check Is Working";
    _centerside = WEST;
    _unittype = ["B_Soldier_F", "B_soldier_AR_F", "B_soldier_LAT_F", "B_Soldier_GL_F"];
    _unit1type = _unittype call BIS_fnc_selectRandom;
    _unit2type = _unittype call BIS_fnc_selectRandom;
    _unit3type = _unittype call BIS_fnc_selectRandom;
    };	
    if (_roadblockside == "AAF") then {
    //hint "Side Check Is Working";
    _centerside = RESISTANCE;
    _unittype = ["I_Soldier_F", "I_soldier_AR_F", "I_soldier_LAT_F", "I_Soldier_GL_F"];
    _unit1type = _unittype call BIS_fnc_selectRandom;
    _unit2type = _unittype call BIS_fnc_selectRandom;
    _unit3type = _unittype call BIS_fnc_selectRandom;
    };
    ...
    

  • Dynamic Whole Map ArmA3 Missions by SaOk, ConstructFuncs.sqf:
    if (_class in ["Land_TentA_F","Land_CampingChair_V1_F","Land_Cargo_House_V1_F","Land_dp_smallTank_F","Land_dp_smallFactory_F","Land_dp_mainFactory_F","Land_MilOffices_V1_F","Land_Radar_Small_F","Land_Radar_F","Land_TTowerBig_2_F","Land_TTowerBig_1_F","Land_Pallet_F","Land_Scaffolding_F","Land_Shoot_House_Wall_Long_F","Land_Mil_WallBig_4m_F","Land_Mil_WiredFence_F","Land_PowerGenerator_F","Land_PortableLight_double_F","Land_PortableLight_single_F","Land_FieldToilet_F","Land_Sink_F","Land_CampingTable_F","Land_Camping_Light_F","Land_WoodenTable_small_F","Land_ShelvesWooden_F","Land_TableDesk_F","Land_ChairPlastic_F","MapBoard_altis_F","Land_TBox_F","Land_TTowerSmall_1_F","Land_CncWall4_F","Land_LampHalogen_F","Box_IND_Wps_F","Land_HelipadSquare_F","FirePlace_burning_F","Land_TentDome_F","Land_HBarrierWall4_F","CamoNet_BLUFOR_F","CamoNet_BLUFOR_open_F","CamoNet_BLUFOR_big_F","Land_BarrelWater_F","Land_BagFence_Long_F","Land_BagFence_Round_F","Land_HBarrier_3_F","Land_HBarrier_5_F","Land_HBarrierBig_F","Land_Razorwire_F","Land_Crash_barrier_F","Land_BarGate_F"]) then {
    if (pisteet >= _cost && {isNil{_post getvariable "StaticO"} || {count (_post getvariable "StaticO") < 78} || {!GUARDLIM}}) then {
    _veh setvariable ["Ghost",nil];
    _veh setvariable ["AmCrate",1];
    if !(_class in ["FirePlace_burning_F"]) then {[_veh,0] SPAWN VehLife;};
    _nul = [-_cost, "Construction",side player] SPAWN PRESTIGECHANGE;
    pisteet = pisteet - _cost;
    if (_class in ["Land_TentDome_F","Land_TentA_F"]) then {
    _post = ([(getposATL _veh)] CALL RETURNGUARDPOST);
    _post setvariable ["CampV",1];
    //(_post getvariable "Gmark") setMarkerText " Guardpost with tent(s)";
    };
    
    _post = ([(getposATL _veh)] CALL RETURNGUARDPOST);
    if !(_class in ["Land_Cargo_House_V1_F","Land_dp_smallTank_F","Land_dp_smallFactory_F","Land_dp_mainFactory_F","Land_MilOffices_V1_F","Land_Radar_Small_F","Land_Radar_F","Land_TTowerBig_2_F","Land_TTowerBig_1_F"]) then {
    _earlier = _post getvariable "StaticO";
    _id = "N"+(format["%1",count _earlier]);
    _post setvariable ["StaticO",_earlier + [[_class,getposATL _veh, direction _veh, (surfaceNormal (getposATL _veh)),_id]]];
    } else {
    _earlier = if (!isNil{_post getvariable "StaticOS"}) then {_post getvariable "StaticOS"} else {[]};
    _id = "NS"+(format["%1",count _earlier]);
    _post setvariable ["StaticOS",_earlier + [[_class,getposATL _veh, direction _veh, (surfaceNormal (getposATL _veh)),_id]]];
    if (_class == "Land_dp_mainFactory_F") then {[getposATL _veh,"Fac"] CALL SAOKCREATESTPOINT;};
    if (_class in ["Land_dp_smallFactory_F","Land_dp_smallTank_F"]) then {[getposATL _veh,"Sto"] CALL SAOKCREATESTPOINT;};
    if (_class == "Land_MilOffices_V1_F") then {"MilOff" CALL SAOKADDPROG;};
    if (_class == "Land_Radar_Small_F") then {"RadarS" CALL SAOKADDPROG;};
    if (_class == "Land_Radar_F") then {"Radar" CALL SAOKADDPROG;};
    if (_class == "Land_TTowerBig_2_F") then {"MilTower" CALL SAOKADDPROG;};
    if (_class == "Land_TTowerBig_1_F") then {"MilTower" CALL SAOKADDPROG;};
    ...
    


    ^^ Very interesting, isn't it?
    Too bad he has to hardcode classnames to do such a thing... :(

  • ...and so on, and many more. And each one of those guys has to maintain these various lists by hand; or new things simply won't work. Have fun porting such things to a new map, or integrating new factions and such stuff... All those hours of precious manpower lost, just because CfgVehicleClasses is a joke. All those awesome ideas never carried out, because they were deemed to be infeasible. All those missions or factions and other toys never played with, say on the latest fancy map that just got out.
    It's depressing. :(

^^ Fixing this for sure could have a leverage effect on the whole arma ecosystem. :cool:

My examples were over the top on purpose to illustrate the freedom available, while using nodes from your post. More common examples would probably be in the lines of:

"BLUFOR", "Desert", "Helicopter", "Tandem Rotor", "Transport"

"OPFOR", "CSAT", "Urban", "Marksman"

"AAF", "Truck", "Transport"

"Civilian", "Beachwear"

"Russia", "Tracked", "Anti-Air"

In the examples you've given, there are authors who make a pool of objects that they want to pick from on purpose (If you think "Habitable Greek houses with white walls, red roofs, intact doors and windows" that better fits into a tree structure than a descriptor structure then I see no point in discussing this anymore), and authors who would have literally needed at most two supercommon tags like "BLUFOR" and "Sniper" to get what they want.

Freeform, "creative" and "willy-nilly" of the tags is their actual purpose to allow the content maker to describe their content without being constrained by a rigid structure that someone else maintains, and 2 months in you get feature requests for "Habitable", "Greek", "White Walls", "Red roofs", "Intact doors", "Intact windows" leaf nodes to be inserted somewhere, which then takes a commitee of maintainers to agree on what node it sits. But in turn, tags system requires only community adoption and could be coded up in an evening by any one of us here.

And besides, there's no way you'll eliminate every single case of custom pre built arrays where you actually want a certain specific subset of things that might span multiple different parameters.

Share this post


Link to post
Share on other sites
Let's have a look at another example maybe: a module-maker wants to find all structures related to electricity on a given map, but he can't know in advance what kind of objects (addons) will be present. Thanks god things are tagged in a "meaningful" way. Having a tag set ["structure", "electricity"] would be a good start, but we can do better - similar to defining infantry roles.

And what if i want to make a water grid instead? You can't possibly predefine all things you ever would want to know. You could make custom things, yes, but then you are back to square one and have to maintain the entire tag system for everything. And instead of writing your own class like those examples do, you would have modify the configs of every affected class instead, which only work with mods. And missions like to avoid beeing a mod as well.

Eh..., I could do what by myself now?

You can write custom classes/tree structures, you can add whateveryounameittag[]={} to vehicle config entries . You can't replace CfgVehicleclasses and its implementation in the editor but there is no need to atm. You can write functions for handling the tags / your class tree.

Edited by X3KJ

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×