The State of LUA in DDA


#1

I was led to believe the LUA in DDA was going the way of the dodo (https://github.com/CleverRaven/Cataclysm-DDA/issues/20819), but there also seems to be some currently active work on expanding the LUA infrastructure (https://github.com/CleverRaven/Cataclysm-DDA/pull/21744).

Has the effort to remove LUA scripting from DDA been abandoned? Or only abandoned in certain aspects? If the latter, is there any documentation one what parts of the LUA infrastructure are being expanded and what parts are being factored out (beyond what’s available in the issue tracker)?


#2

Lua is still on a block and @kevin.granade would probably axe it somewhere after 0.D.

Other Lua-related sources are touched here and there in various PR in a kind of a maintenance.

There are two opened PRs with new Lua features and I would like to have them merged before 0.D, but it is not up to me to merge them:

  • one adds several new callbacks and more important system to provide callback parameters;
  • the other one exposes three new functions which will simplify some modding things.

There are also two very interesting branches by @BevapDin without PRs yet:



#3

Lua state is already rather functonal now and you can start creating new mods. Below are some links to example mods to start with:

https://discourse.cataclysmdda.org/t/14117

http://smf.cataclysmdda.com/index.php?topic=14825.0

http://smf.cataclysmdda.com/index.php?topic=14861.0


#4

Neat, thanks for the informative reply!

If I get this right, the reason Lua is being removed is that few mods use it and you would like to expand the number of mods that use Lua so that the maintenance requirement to support the scripting language is worth its continued inclusion?

If I am understanding this correctly, then has @kevin.granade specified what exactly he wants to see in Lua-based mods to make the maintenance requirement worth it? I’m trying to get a handle on how much would be required to demonstrably illustrate the usefulness of Lua in the game at the current state.

From what I’ve seen (and, admittedly, I’ve really only glanced over things), Lua is not being used in it’s best suitably in DDA right now. The best use-case I can see for Lua is in dialog trees, quests, and NPC interaction which require rapid prototyping and evolution (even a few seconds to recompile after every change adds up), but there doesn’t seem to be much support for Lua in this area. Is this because those aspects of the game are simply not well developed in core code support at the moment?

Thanks again for your answers!


#5

I agree with these statements, and they outline the core weakness of our LUA infrastructure. Instead of saying, “what is LUA good at?” then adding support for those things, the approach was “LUA is used for scripting in games, so let’s add it”. As a result, you can do a bunch of essentially random things in LUA, but there is no coherent or comprehensive support for doing things that LUA is good at in LUA. Even worse, since there’s no plan or goal to outline what good LUA support should look like, the only solution to “fixing” LUA integration is externalizing more and more game state, which has a terrible cost/benefit ratio.

This is probably the most complete rationale that I’ve posted, and in broad strokes it’s the same as what you pointed out, there’s nothing wrong with LUA, but the way we’re using it is deeply dysfunctional.

So, to address your question:

I have not, specifically because I don’t know what working LUA integration would even look like. Just piling more mods that use LUA on isn’t going to fix the fundamental problem:

In short, the current LUA support does not make it faster to add things to the game, it doesn’t work. Every line of LUA in the game is backed by 10+ lines of C++ infrastructure, that ratio is unsustainable.

What I would need to see for LUA integration to remain is a convincing argument/plan for:
What LUA is good/essential for.
What bindings are required to enable that functionality.
An outline describing how the amount of c++ and binding code required to make that happen is dwarfed by the increased productivity of using LUA for that task instead of coding it in c++ or json directly.
An argument outlining why JSON plus a judicious amount of C++ can’t do the same thing.

Even with those arguments successfully made, I would still be axing most of the LUA bindings, specifically the ones that are not needed for the use cases identified in the plan. Even if LUA has a good use, we still need to trim the fat, because right now there’s an absurd amount of game state exposed to LUA, and the vast majority of it is unused.

Side note, I’ve become really sceptical that embedding LUA is as productive as people keep claiming. I keep running across things like this where we find out that LoL heavily uses LUA (oh hey they’re super successful, so it must be working), only to have it clarified that it’s now considered 100% tech debt, and that it was a mistake to use it, and that they have a large and very expensive proposal to root LUA out because it’s causing major problems.


#6

(The use case mentioned on your last link there was for a specific circumstance for which Lua was absolute overkill, not necessarily that Lua itself was impractical for the game. More accurately, they literally use Lua produced by a code generation tool to call every single function in turn, rather than using Lua to write scripts or making use of Lua’s own ability to work with data. Using Lua as a batch engine is definitely the wrong way to use it.)

I missed your replies on the old thread on the SMF board, so apologies for that. Anyhoo, long story short, when I decided to come back to Cataclysm’s new builds last week, and then noticed a couple days ago that Lua support was still in, I was a little surprised and decided to check and see if Zhilkin had managed to convince you to keep it.

Guess not. =)

To answer your “essential” question in a perhaps glib way, Lua (or scripting in general) is essential for one thing and one thing only: modification of game logic as part of data-driven design (not to be confused with data-oriented design, which is basically C code working with master object tables). Here’s a Stack Exchange thread which has a bunch of great statements and linked articles on why data-driven design is valuable, including from one person who wrote an article literally titled “The Case Against Data-Driven Design” without irony, and yet who still wholeheartedly supports data-driven design. =)

As I mentioned last time in way too many words, Lua’s “fundamental problem” is not the ratio, but the chicken-and-egg problem; Lua support is rudimentary if existent at all, which prevents mods from using it, which prevents features from being requested or added, which makes Lua support rudimentary if existent at all. In other words, I do think that piling on more mods literally is the fix to the problem. Zhilkin’s example mods are sometimes a bit blithe or silly, but having tried to work with the scripting as it exists (just to allay any illusions that were conveyed from the last time, I actually don’t know Lua myself!), the existing Lua support is only useful for the most blithe and silly tasks, and yet attempts to add more generally useful functionality (more events, more map interactions, more exported data structures, etc.) are being ignored. That line count of procedurally-generated code is somewhat disingenuous: those lines are all dead code until/unless anyone uses them, which means no performance impact on anything other than the compilation process – which the data-driven approach attempts to sidestep in the first place. Then they’re no longer dead code; they’re live code, being called by actual rapidly-prototypable and rapidly-mutable Lua functionality, which people can externalise gradually and leave the game engine to focus more robustly on the data-handling structures. This cost/benefit ratio approaches zero; it’s not the externalisation in itself that’s the end goal, but the ability to modify the externalisations.

Lua does not increase productivity, especially not of core engine programmers. It increases mutability. If anything there will always be a negative impact on productivity for the game engine and perhaps on the people who are accustomed to doing gameplay programming directly in the engine. Mutability is the factor we’re trying to isolate: the ability to change the game quickly and rapidly to suit a wide variety of perceived goals and interests rather than being forced to reach consensus.

In other words, the idea behind scripting isn’t solely to externalise engine support in the root build, if the programmers are the ones doing the design – you already have direct access to everything you could possibly want. The externalisation of engine features is designed to give designers and especially end users the agency to create their own changes: plotlines, stories, balance, esoteric features, characters, cheats, etc. It’s tacitly useful to externalise the content in the root build so that it can be changed quickly by end users whenever they want. Having to recompile the entire project to change a single undesired feature is both difficult and unsustainable, given the whole iteration-versus-recursion thing I mentioned last time, but freedom is a big part of it.

In my case, I want to add realism content, story related content, and gameplay related content that is subjective enough that people wouldn’t want it in the whole; e.g., intense vehicle realism and physics; rebalanced map generation; Sims-like NPC personality variables, interactions, conversations, relationships, romances, reactions to your behaviour, etc.; negative morale accumulations when near brutality, like pulping zombies, standing in the midst of a room covered in blood and gore, suddenly spotting a bunch of human bodies, etc., inversely proportional to discipline and insanity; manufacturing equipment to mass produce parts like steel plates and re-establish industry (giving a function to every Macguffin machine that appears in factories); and so on.

These can be introduced into the core game, sure, but when subjective content is automatically distributed to everyone, negative reactions are common even if they have the option of turning it off (heck, I’m sure most people are already working up a list on the things I mentioned there). On the other hand, people tend not to be bothered by subjective content that they can locate and opt-in for instead. The maintainability is also a thing. Anything that has to be mainlined does have to be maintained, but outside the mainline only the original author is responsible for it and if it becomes obsolescent, then it’s the author’s responsibility – and, dependent on the permissions given anyone else can step in to maintain it if they want. Opening up external mods and content with scripted game logic allows good content to gravitate and bad content to deprecate, without any particular burden on the main build other than the (admittedly substantial) effort of keeping the engine portable enough to allow external scripts in the first place.

Because we don’t have functional game logic in Lua, I can’t provide an example, but playing a moddable major studio game should provide all of the necessary examples of what’s needed in a scripting language. Even then, people will be hurting for more scripting language functionality; the most useful scripting language is the most feature complete, not the one that’s pared down to the arbitrarily-defined features that fulfill the desired use cases. The purpose of scripting is to fulfill all of the use cases that the game doesn’t fulfill on its own, and therefore there will never, ever, ever be a version of Lua with minimal bindings that will be more useful than core engine code.

So, presuming it’s axed, you have only one of two choices.

The first choice is to require all scripted mods to merge their very specific subjective code into the cohesive whole, which acts as dead code unless a mod uses it. That conveys all the attendant penalties, such as veto, debate, bloat, and, as the article you linked mentions, “debt” from maintenance.

Working on the master is also inherently, although subtly, a form of subordination: instead of being permitted to write your own content that suits your own purposes, you must write content to suit someone else’s purposes – not just yours-as-Kevin’s specifically, but the community-at-large’s as well, which can introduce the “tyranny of the majority” concept we see in criminological contexts (the notion that sometimes it is most just to ignore everyone and do what’s morally right rather than succumbing to the mob). Some people like working with a team, still others like the game enough that they are willing to roll with it, some people reject it and would prefer to work alone (me, for example), and the occasional Others create the drama that this community sees from time to time (also me, I guess ;-)). (Another counterpoint is, do you feel like the Lua support is a mob that you are subordinate to, I guess.)

In addition, C++ is not simply something that can be set up easily. To come perilously close to ad hominem, but with a good intention, is your dislike of Lua and desire to remove it based on not wanting to learn it? I don’t compellingly want to learn it, either, but my operating system and expertise is far more oriented toward design and not oriented toward programming, and I imagine a fair few other people are of the same category. Working directly with C++ has a much higher bar to entry than writing game logic in Lua does. People on *NIX systems have the advantage that because the OS is designed by programmers for programmers, build environments are pre-installed and practically part of the kernel itself, and it’s as simple as a few apt-gets and lines in the console to do rapid prototyping on their own. On Windows, which is actually a substantial majority of any user base (also a chicken-and-egg problem, but that’s another rant), people who have limited programming experience would simply prefer to learn something “simpler” and work within an engine than to go through all the necessary steps of managed code to integrate into a single project and the whole. (A favourite statement of mine is, if I have to set up a development environment to work on someone else’s game, why wouldn’t I just work on my own game instead?)

The other option, which is really a non-option, is to require independent forks of the source code that will never be reintroduced into the whole. That still has all of the penalties for end-users of working with code.


The reason why Bethesda’s games are so popular and why most of the work over the last few years that should have been spent on my own game has instead been on modding theirs (in spite of their absolute horror show of a game engine, voice actors ranging from decent to atrocious, and abortions of plot) is because of the longevity provided by their modding community as well as the easy approachability of the modding process. (Valve/Bethesda like to make silly claims like “only 3% of users use the Workshop” – discounting the substantial number of people who use mods via other external communities, or few who write their own.)

Cataclysm’s engine is at least halfway decent (especially for a roguelike), but has a lot of subjective content in it that players are essentially forced to accept. The game changes substantially with experimental builds, usually for the better… but, for example, the case of the backlash against the corpse nymphs is another. Some can be modded out, but certain gameplay behaviours are literally stuck unless you have the programming talent and attitude necessary to jump into the main build, describe the importance of your feature, and then (if you’re one of the dozen or so active people who also directly contributes) either a) support both your alternative and the original with the source changes you make or b) convince the majority that they must adopt the changes if making it an option is either unfeasible or undesirable.

With externalised game logic, this occurs emergently rather than deliberately. This is all regardless of the language. If a single core engine is maintained with external scripting available, in any language – Python, Java, hell, even JavaScript as AngelScript – then designers are given the ability to write program code without, you know, writing program code. This attracts independent narratives and expansion over geologic time, rather than brightly-burning-bulbs that furiously add amazing features to a single room and then burn out.

In other words, Lua itself? Couldn’t care less about it. Scripting? Absolutely imperative, and the vast majority of scripted content that’s in the game does need to be exported from low-level code to high-level code so that people have the option of changing it and balancing it, rather than having to do everything by committee. That’s fundamental to modifiability and allowing interested people the ability to create and tweak to get the game experience they want. Cataclysm is excellent without it, but could be transcendent with it.

Since Lua’s the scripting language we’ve got, I’m defending it vigorously unless some other alternative is proposed – if we were going for anything, I’d actually prefer Python (which I also don’t know, at least not very well =)) since that also gives us the ability to run external OS-dependent DLLs/libs/shared-objects/what-have-yous, but Python is allegedly one of the worst things to link to anything ever and although its bytecode interpreter is still rather fast, its compilation and JIT is much slower than Lua’s.

You do bring up an interesting point: there is literally no advantage to using Lua over judicious use of engine-supported JSON, provided that the JSON enables all of the matching functionality. But since you’d need the same full writeup of intended bindings for either engine-supported JSON or just external Lua, I think Lua’s the way to go there.


#7

That is not making sense to me. Dda is very heavily data driven in exactly the way outlined in those articles, the majority of game content is externalized to json. What you seem to be saying is that not only the data, but also the game logic should be externalized to data, but that’s not the actual result of injecting LUA, that externalizes game logic as code, at which point it’s a weird circular argument of “we can’t write code, so add lua so we can write code without writing code”.

In other words, it still just boils down to compilation, the only reason to use LUA over c++ is because you can’t or won’t write your changes in c++ and submit them for inclusion in the main project. As far as I can tell, the only reason LUA modding support thrives is that closed source software throws up artificial barriers to modification of the core game.

Let me clarify, dda is not a game engine, it is a game. “Enable people to change anything about dda without forking the project” is not a development goal, and I’m not interested in spending meager project resources on making it happen.

I’m not saying that can’t work, I’m saying it’s an extrordinarally expensive way to proceed and I don’t want to pay the price to make it happen.

That is not remotely true, if we were to commit to a truly pervasive LUA modding system, every change to any (internal!) game interface must be scrutinized for regressions to the matching LUA interface. Changes that adjust behavior of LUA interfaces must be made backwards compatible or cancelled, new internal interfaces must be either determined to be inconsequential or have matching LUA interfaces added. This is an incredibly expensive proposition. The compilation overhead is inconsequential in comparison.

Returning to the data-driven design point, the desired state is to allow designers to write declarative content that is loaded by the game. Allowing injection of executable code actively subverts this concept. It prevents the formation of well-defined interfaces for injecting data because it’s much easier to just expose all the internal game state to your injected logic, and let the logic side do whatever it wants.


#8

Actually, I didn’t try to.


#9

I only meant your desire to keep it around, e.g., your reddit post. “I want to promote using it to prevent it from being axed.” =)


#10

I wanted others to start convincing Kevin by making mods, so I started to provide examples. Apparently no one was interested.


#11

True to the can’t/won’t (more won’t than can’t, but can’t’s a part) and true to the Lua support being more common among closed-source projects, but the game engine goal is indeed what I’m arguing for. It’s quite possibly one of the stronger survival oriented game sandboxes and it already has everything readily able to be adjusted, save for a robust scripting language. Fallout: New Vegas was also designed to be a game (and bugs withstanding actually is quite excellent without mods), but even then is still far more fun in sandbox gameplay, a function for which it was never intended, especially if the Tale of Two Wastelands content is merged in. Skyrim is not even a contest between the game and the sandbox. In both cases, modding efforts almost always retain the underlying game as the foundational glue, but the unique experiences and customisations that players can introduce then turn it into something better… much better in the latter case. (I couldn’t stomach vanilla Skyrim for more than 11 hours, and those were very generous “well maybe it gets better” hours. Modded Skyrim, I’ve been going strong for 1600 hours.)

Without any non-self-taught programming skill or experience I’m almost certainly underestimating the effort involved, but I do see it as having the foundation already there and the work to add onto it would justify the expense in the long term. I have no proof other than other successful examples of the same in the closed-source world and my allegation that scripters who are non-programmers/non-sprite-artists are an untapped talent pool, however.

I’m not suggesting the whole game be available to logic – just the scripted bits that manipulate the world and the player character, like item-uses, activating biomods/mutations, tile examination actions, map generation, spawning of creatures from rot (pretty much the ideal use of external gameplay logic), creature evolution, etc; the 90% of code execution time that occurs in 10% of the code not only should remain in the engine but simply must.

As long as there’s an ability to tweak the results of anything either by polling-and-overruling or by occasional corrective factors, much of the code is fine in-engine. In the end, tweaking is the desired panacea – direct manipulation of the results that the game produces if an end user doesn’t particularly agree with them, so that they’re not forced to go full redneck and head to the hills whenever they find a feature they don’t like. =) The hard-coding and magic numbers of actual in-game environments like Necropolis, for instance, is a big no-no in my books (even in spite of how awesome Necropolis is – I probably wouldn’t change anything).

I suppose I’m still arguing the point without satisfying the conditions of “what bindings”. I can at least list from personal experience what I’ve wanted in the Gamebryo-based games; the game engines already do a great job of data-based dialogue and missions, with conditional logic on what message should be displayed when choosing a particular dialogue option even without actual scripting to do so. Where they tend to fail is their ability to produce reasonable results for adding gameplay-related features or scanning for interactive objects around the player (something that Cataclysm’s scripting language is also a little sparse on), and especially for direct access to actor variables, object trees, and game physics. FNV’s really functional for direct interaction, like triggering a lever, but requires obscene workarounds like cell scanning to apply tweak-level manipulation of characters, since each actor has only a single “one-to-rule-them-all” script that inhibits inter-mod compatibility unless everything is merged together.

For example, my NPCs-use-ammo mod for New Vegas uses the scripted logic to scan for everybody around the player, get a list of all of the items in their inventory, find the matching base class that corresponds to that inventory item instance, and then set the flags on those base classes to compel NPCs to use ammunition for those weapons (incidentally exposing a couple engine bugs on features they didn’t fully test with NPCs that do use ammo, like revolver reloading). If I had direct access to the object classes as a tree, that effort would be simpler, but that’s not available. This mod could have been done as direct modification of the objects, but then would not be automatically compatible with other people’s mods, as the “rule of one” of modifying a single weapon record’s field means that the entire weapon record needs merging. (I hard-coding a list of most object types for faster execution, but that isn’t mod compatible either, so the script needs to hack everything all the time.)

Cataclysm is both good and bad at JSON-based modifications like this: “copy-from”, “relative”, and “proportional” work wonders, but anything more intensive than that also follows the rule of one.

As a prototype of bindings that I would probably personally use:

  • Retrieve array of master object table for fields, NPCs, monsters, objects, vehicles instances
  • Retrieve all fields, NPCs, monsters, objects, vehicles of type within radius of singular point
  • Retrieve type of tile at point (already in!)
  • Get player’s X coordinate and Y coordinate (already in!)
  • Get player’s overmap X and Y coordinate
  • Find overmap tile of type in radius of player, return coordinates if found or nil if not found
  • Get overmap type player is currently in
  • Get overmap type at tile
  • Replace overmap tile with another overmap tile
  • Regenerate terrain for overmap tile
  • Respawn monsters for overmap tile
  • Get instance of object of type within singular point (can be soft coded if above are available)
  • Start internal or scripted task for an NPC or creature (“move to point”, “use furniture”, “travel to overmap”, “find overmap tile of type”, “find item of type”, “attack target to kill”, “flee”, etc.)
  • Directly manipulate an NPC, creature, or object instance (teleport, move, collide, edit instance parameters (mostly already in!))
  • Directly manipulate an NPC, creature, or object base class (root statistics)
  • Accelerate vehicle
  • Decelerate vehicle
  • Trigger vehicle skid
  • Flag vehicle as mobile or immobile
  • Apply arbitrary morale modifier to player
  • Apply specific morale modifier to player with desired duration
  • Add effect to NPC or creature (already in!)
  • Force NPC to fire once at coordinate and/or actor in that coordinate
  • Trigger scripted autopilot of player character with a brief realtime delay between successive statements, returning control to player after completion
  • Start a mission
  • Set a new mission target
  • Set a mission stage
  • Finish a mission
  • Restart a mission
  • Create a trigger area that will produce events upon entry
  • Auto-save
  • Pop-up to provide message (already in!)
  • Pop-up to select arbitrary item from menu, yielding number selected as event handler
  • Attach runtime-created variable to an instance (e.g., create arbitrary variable named “fnord”)
  • Set, manipulate, and pull the value of runtime-created variable on instance
  • Save or discard runtime-created variable
  • Event handlers:
    ** Periodic heartbeat (already in!)
    ** When player or character consumes a consumable (parameters: character, consumable, amount left (0 if gone))
    ** When player activates a furnishing (params: character, furnishing)
    ** When player or character strikes NPC with weapon or bullet (params: NPC, character, weapon used), return value determines actual damage that would be caused (giving ability to modify result)
    ** When player or character strikes NPC with explosion firearm (same parameters and return value effect)
    ** When monster strikes character or player with attack (params: character, monster[, attack used]; if multiple attacks added to game)
    ** When player or NPC picks up an item (character, item)
    ** When player enters line of sight of monster (player, monster; possible to recycle safemode code for this)
    ** When there are no hostile entities remaining around player for several turns (similar recyclability)
    ** When player is killed (params: killing creature/character, method of destruction)
    ** When monster is killed (params: monster, killing creature/character, method of destruction)
    ** When NPC is killed (params: NPC, killing creature/character, method of destruction)
    ** When object is destroyed/disassembled/burned/otherwise deleted (object, method of destruction)
    ** When a new character is loaded (params: player)
    ** When a saved game is loaded (params: player)
    ** When the game is saved (params: player)
    ** When an effect is applied to the player or a character (params: character)
    ** When the player starts a mission (params: player, mission)
    ** When player, character, or creature enters a trigger area (params: creature, trigger area)
    ** When player, character, or creature exits a trigger area (params: creature, trigger area)
    ** When player enters conversation mode with an NPC (params: player, NPC)
    ** When player exits conversation mode with an NPC (params: player, NPC)
    ** When character or creature detects player, character, or creature by sound (params: listener, target, volume of sound, sound heard)
    ** When creature detects player, character, or creature by smell (params: listener, target, intensity of scent)
    ** When character detects sound (params: listener, sound type, approximate origin tripoint)

There’s undoubtedly much, much more that doesn’t come to mind immediately, but that alone is a great start.

Much of that can be done by creating JSON objects that are executed by native code in sequence as if they are scripts, but scripts can cut out the middle man, and some can only be done by scripts (e.g., formula modifiers to damage caused) unless particularly complex design is added to obviate them (e.g., ability to modify a character/monster instance’s damage suffered by weapons with certain flags/keywords both at runtime and as innate vulnerability/resistance).

For the former paragraph, I’m arguing in favour of a fairly pervasive system, but I’m not sure that some 500-or-so gameplay functions would need direct checking against 10000-or-so engine-related classes and features and vice versa. I’m presuming you’re stating “interfaces” in the comp-sci sense, i.e., methods and fields, but isn’t the Lua system already set up just to generate the bindings from plain-text entries? How often do methods get deleted or have their parameters changed and how often do fields get deleted or renamed? If a non-trivial amount, how often is that due to game logic and not due to changes in core mechanics?

Your latter paragraph is a pretty damned good argument, and I would very much love to have the need for scripting obviated by declarative content. =) I’m just not sure how practical it is to keep every declarative feature “in house”, especially with the breadth and scope of some changes that people might want to make. The program code is already crowdsourced, but crowdsourcing both the program code and the scripted logic would give a greater number of people the ability to write their own features independently that are still compatible with (and/or pullable into) the whole.

It could indeed turn out to be the singular worst decision ever made for the project, as it may already seem right now, but I like having faith in community-based design. If nothing else, it’d relieve a lot of forum burden by empowering people to make their own ludicrously stupid gameplay changes themselves instead of incessantly asking for them and having them shot down. (Ahem… like myself, again. =P)


#12

That’s pretty much an impasse, I’m not interested in dda as an engine per se. I’m happy to add data-driven behavior, but only to the extent that it improves dda-the-game.

That’s probably weeks to months of work you just outlined. The basic data bindings aren’t that bad, but all the querying and injection of callbacks and overrides is, and as you say, this is just a start.

I’m not following you, what I mean is every change needs to be scrutinized for “is this going to change how any of the LUA interfaces work?”. This means that someone intimately familiar with the bindings has to review every code change. Alternately, we don’t do that, and the LUA bindings break constantly.

That doesn’t meaningfully change anything, someone still has to manually update those text entries every time a bound method is changed. Someone still has to be watching for those changes in the stream of PRs. Someone still has to write helper methods any time an API can’t be exposed as-is.

I don’t have numbers, but it’s enough to be problematic. Also remember that the benefit to the project is roughly 0, so I’m not willing to tolerate much.

You’re arguing for exposing an absolutely massive amount of game state via scripting bindings, that’s somehow totally fine despite a total lack of feedback about what parts are being used, but exposing actual data-driven bindings is somehow too much? The coordination and synchronization problems are present either way, the problem size is similar, the main difference is one you can implement blindly and the other requires design.
The difference is that data-driven design has been working and supplying benefits to the project incrementally. If anything, the existence of LUA bindings has been interfering with it by applying shortcuts.


#13

@JT1, your use of Bethesda as example really, really doesn’t work.

Not only their code is closed, they have a far larger development team, and they have an audience orders of magnitude bigger, a far more mainstream audience which is going to have a larger proportion of people willing to mod it who don’t have coding knowledge.

Besides, most people willing to mess with the script language of their games are already going to be familiar with coding, and for those that arent? There’s tutorials galore. Cata’s documentation and tutorials are flimsy and out of date enough as it is.

Lua also in no way guarantees you’ll skip the usual modding problems of multiple mods trying to touch the same thing, there’s only so much you can mitigate that, and frankly? Modifying the source code and using Git to merge changes makes it far more likely for things to be compatible than anything you could think to implement from the ground up in Lua.


#14
  1. Those weeks to months of work of adding external gameplay logic will be needed one way or another when work shifts to mission design and interactivity with the world, regardless of whether it’s done in Lua or in an object-based system, and an object-based solution has the additional disadvantage that statements will not benefit from branching conditions with anywhere near as much readability or flexibility.

  2. I’m simply having trouble understanding why every change to methods is going to break Lua support with any frequency at all – i.e., why there is even a scrutiny process at all rather than automated unit testing or just waiting for an actual bug report. The removal or changing of the arguments of bound functions or variables will break support, but additions to code generally won’t. There’d simply be an absence of new bindings reflecting the new features, which in itself wouldn’t be anything worse than unfortunate. If it actually breaks compilation, that’s another matter, of course.

The cost-benefit ratio approaching zero I mentioned implies the denominator is increasing, I might add. :wink: The more popular the project gets and the more people contribute their own modifications to the world at large without having to fork the project or submit it for internal review, the higher the benefit that is realised for the same linear cost, as compared to hard code which is lower fixed cost, but also fixed benefit.

  1. Data-driven bindings are “too much” on the basis of essentially writing a scripting engine where each statement is an object rather than a black-boxed call and return in an embedded language explicitly designed for that purpose. A system similar to StarCraft’s map editor triggers can work, but scripting would get the same thing done far more effectively, and more quickly, without as many esoteric workarounds like the “minions” in League of Legends, the “cloak spells” in Skyrim, and so on.

Scripting also offers greater power and flexibility for the person doing the scripting (especially when it comes to access to program flow control statements such as for/foreach/while loops and branching conditionals, which in my experience scripting is truly awful without). A singular new “generic” function bound to Lua takes only a bit of effort to write a setter/getter, and runs lean and mean, though it incurs maintenance overhead on the back end – a new data-driven event trigger based on an object incurs a larger memory and CPU footprint on the front end and depending on how non-generic it is, also requires a larger amount of new hand-written supporting code to implement.

Since I am indeed probably wearing Bethsoft games thin, another modern moddable indie game with a robust scripting language is Starbound. (I lost around four months’ worth of work on one of my Starbound mods when my hard drive failed last summer, which was a massive bummer… still haven’t gotten back into it.) Anyway, vanilla Starbound ranges from merely okay to good, but modded Starbound is fantastic. The game is also entirely external logic – all of the gameplay logic proper is external, which is an interesting blend between closed-source and open-source, and it’s quite possible to change the entire game to one’s content. Everyone still only makes tweaks to it: it is still Starbound-the-game, yet the modifications that are there fundamentally change the experience, almost universally for the better, because everyone can pick and choose the features they love the most. (There is indeed a rule-of-one incompatibility there, too, if someone overwrites the same core script. But generally mods strive to avoid that whenever possible by just adding their own scripts.)

All in all, I’m getting as tired of arguing this as you are. Ah well. I tried. =)


#15

You should not have been arguing at all. There is no sense in that. All you need to do is to create some mods which will prove that Lua is useful or make some PRs to flesh out Lua bindings. Kevin complained on several occasions for last year or two that nobody is using Lua in large mods (actually even in smaller ones) - no new mods appeared since that time (save for my examples).

If some new large mod would appear - that way Lua could be saved 2016 or 2017. There were plenty of active mergers at that time. I don’t know if it is even possible now with only me, Rivet and kevin (and very rarely others) working with merges, but you have indefinite time until 0.D. :smirk:

I am personally all for Lua to stay and expanded, but I am very disappointed that it is not being used by others and I have limited time to contribute to dda-lua myself.


#16

Now THAT I would be interested in doing.

I also wanted to add more climatic zones to the map.
DF draws the mountains first, then similates wind, temperature and rain. Then places biomes. Then places civilizations (or in our case human cities, which then could crumble to their simulated end, collected in legends).

But how does LUA make one achieve this? I guess its better for this thsn scripting sand banks and island cities.

I however know only how to compile from source. And have been looking for a guide to get to change anything more complex than the starting screen.

But when I lived on a small tropical island in the middle of the ocean I dreamt of C:DDA taking place there as well.

Would have loved to set up a tent in the main road junction, cleared of people. And set out to scavenge drinking water from whereever and other stuff from the Shops nearby. MaleCityMaldives


#17

Is it possilbe to write a mod in LUA, which would iterate through all items and set “spoils_in” to 0 (to never spoil) for all items where “spoils_in” > some number ?

Edit: by item, I mean item type, not all items that are existing in the world


#18

All items like where? In player inventory?


#19

item type, not all items that are existing in the world, sorry for messy wording


#20

Won’t be possible right now.