Lua may be getting axed, how many people care?

I’ve seen several mods that are changing item groups (which is possible without lua) and one mod that adds two iuse actions. I doubt it is good reason to keep lua.

Well, there is this one, that makes the zombies tougher and tougher as time goes on, and when it does, you have a nightmare.

http://chezzo.com/cdda/Nightmare.zip

that ninja mod adds iuse functions.

its actually quite the mod. wide in scope and with small touches

Is there any place where all the Lua functions are documented? Or do you just have to check catabindings.cpp for how to use them?

Check example mods in https://github.com/CleverRaven/Cataclysm-DDA/tree/master/doc/sample_mods

Also all LUA bindings are automatically extracted to https://github.com/CleverRaven/Cataclysm-DDA/blob/master/lua/class_definitions.lua

That will be useful. Thanks.

Any reasons why (presumably) only the Japanese modding community cares enough about Lua to actually use it, and will that be enough to prevent Lua getting axed? Some of those mods are quite impressive sounding (although I’ve never installed them).

My top guess is that English-speaking developers find it easier to add their functionality to the main repository using c++.
I haven’t had a chance to look over the japanese mods, but there’d have to be some really elaborate use of LUA to make me change my mind at this point.
I’m planning on replacing LUA-based code with behavior you can configure with JSON wherever possible, so hopefully little to no features will be lost.

[quote=“Kevin Granade, post:28, topic:13488”]My top guess is that English-speaking developers find it easier to add their functionality to the main repository using c++.
I haven’t had a chance to look over the japanese mods, but there’d have to be some really elaborate use of LUA to make me change my mind at this point.
I’m planning on replacing LUA-based code with behavior you can configure with JSON wherever possible, so hopefully little to no features will be lost.[/quote]

– MOD NINJA.
game.add_item_to_group(“museum_misc”, “ninja_tengu_mask”, 5)

function iuse_ninja_afterimage(item, active)

local SCREEN_RADIUS = 2
local CHARGES_PER_USE = 25

if item.charges < CHARGES_PER_USE then
	game.add_msg("Power is insufficient...")
	return
end

local num_of_image = 0
for x = (-1 * SCREEN_RADIUS), SCREEN_RADIUS do
	for y = (-1 * SCREEN_RADIUS), SCREEN_RADIUS do
		local point = player:pos()
		point.x = point.x + x
		point.y = point.y + y

		if g:is_empty(point) and game.one_in(3) then
			game.create_monster(mtype_id("mon_ninja_afterimage"), point)
			num_of_image = num_of_image + 1
		end

		if num_of_image >= 7 then
			break;
		end
	end
end

if num_of_image > 0 then
	game.add_msg("I copied the afterimage on the screen of the fog.")
else
	game.add_msg("I could not image the afterimage.")
end

item.charges = math.max(item.charges - CHARGES_PER_USE, 0)

end

function iuse_ninja_typhoon(item, active)

local CHARGES_PER_USE = 100
local TYPHOON_RADIUS = 10
local VORTEX_SPAWNRATE = 0.05		-- per a tile.
local THRESHOLD_DESTRUCTION = 600	-- t_wall.bash_str = 210, t_wall_metal.bash_str = 600

local RUBBLES = {}
RUBBLES[0] = "A mountain of rubble"
RUBBLES[1] = "A mountain of rubble (rock)"
RUBBLES[2] = "Wreck (metal)"
RUBBLES[3] = "A mountain of ashes"

if item.charges < CHARGES_PER_USE then
	game.add_msg("Power is insufficient...")
	return
end

for x = (-1 * TYPHOON_RADIUS), TYPHOON_RADIUS do
	for y = (-1 * TYPHOON_RADIUS), TYPHOON_RADIUS do
		local point = player:pos()
		point.x = point.x + x
		point.y = point.y + y

		-- *Cleaning* ter & furn.
		local bash_str = map:bash_strength(point,true)

		if  bash_str < THRESHOLD_DESTRUCTION
		and game.one_in( math.floor( bash_str / THRESHOLD_DESTRUCTION * 10 ) )
		then
			map:destroy(point)
		end

		-- try remove rubbles.
		local fname = map:furnname(point)
			-- "furn_at" was removed.
			-- "furn" function returns "furn_id" but cant instanciate,
			-- therefore i have no idea to compare id & id. i want furn& :(

		if (
		   fname == RUBBLES[0]
		or fname == RUBBLES[1]
		or fname == RUBBLES[2]
		or fname == RUBBLES[3]
		) then
			map:furn_set(point, furn_str_id("f_null"))
		end

		-- spwan vortex.
		if g:is_empty(point) and game.one_in( math.floor((TYPHOON_RADIUS * 2)^2 / VORTEX_SPAWNRATE / 100) ) then
			game.create_monster(mtype_id("mon_vortex"), point)
		end
	end
end

item.charges = math.max(item.charges - CHARGES_PER_USE, 0)

end

game.register_iuse(“IUSE_LUA_NINJA_AFTERIMAGE”, iuse_ninja_afterimage)
game.register_iuse(“IUSE_LUA_NINJA_TYPHOON” , iuse_ninja_typhoon)

I’m curious, how would that work code-wise?

And this other too -- MOD Nightmare.local MOD = {}mods["Nightmare"] = MOD-- origianl status - Pastebin.com

I also heard there was another mod that made a water-world.

Cool, there is an actual (oceanic/Lake based) water world?

I always wanted to make undead infested nuclear aircraft carriers (with jets and helicopters), nuclear submarines/minisubs - a claustrophobic trapped scenario + impending doom deep under the ocean due to limited and depleting food, water (and perhaps oxygen if the oxygen generators malfunction/sabotage/run out of energy) supplies - forcing you to fix and/or take over control of the sub, in order to head back to the water surface or die by suffocation, starvation, radiation (damaged nuclear reactor), nuclear/conventional missile detonation (due to sabotage/damage by zombies, damage by fire) or simply by being swarmed and eaten alive - kinda similar to the lab escapes but worse.

Furthermore, other ships such as Littoral Combat Ships/Coastal Defense Ships/Amphibious Assault Ships, where one could launch from and return to, your Littoral Combat Ship within the safety of your amphibious tank!), helicopter carriers (launch your raids from your own helicopters!), Drone carriers (massacre zombies with your drone legion), (Guided missile)destroyer ships, Engineering ship (mobile ocean-based factory), hospital ships (crawling with advanced undead types, but also much needed medicine and tools) and/or civilian Cruise Ships, Mega oiltankers, Mega Cargo Ships of Oil Platforms in the game, all came to mind, but there was not enough water surface and water depth to make such very large ships happen. And not to forget, Large fishing ships such as big fishing trawlers to catch all those fish (and occasional Landshark/Undead LandZhark - think the ZHulk + Shark that is a significant threat even at end game situations, both on land as well is in water).

This water world seems like exactly what I needed.

Alternatively, oceanic coastal or lakeside areas with boats would really be awesome too! Just rush to a boat, clear it out of all hostiles, and head to safety of the open seas and hopefully find a nice little island/oil platform to make your base. Failing that make your boat into a mobile base (kinda like doom-mobile but on water), and raid the coast at your leisure with your boat(s)!

I’m curious, how would that work code-wise?[/quote]
It depends on what exactly the mod does, but in most cases it will mean translating the logic to c++, then just turning on and off (and possibly configuring) the behavior with a mod option instead of coding it in LUA.
In a lot of cases, like StatsThroughSkills or FasterZombes, it’ll just be a matter of making a scaling factor available that can be set by a mod.
It looks like the ninja mod adds some item or trait behavior, we would just impliment that behavior in the core c++ code, and allow mod-only items or traits to use it.

i really want to do some things in lua that im pretty sure can’t be done in json. what are things that json can and cant do and how many of the cants does lua take the place of? also im having a lot of issues trying to figure out how to mod this game, is there some json documentation lying around somewhere? :V

also i need a list of lua callbacks pls

[quote=“Cassumbra, post:33, topic:13488”]i really want to do some things in lua that im pretty sure can’t be done in json. what are things that json can and cant do and how many of the cants does lua take the place of? also im having a lot of issues trying to figure out how to mod this game, is there some json documentation lying around somewhere? :V

also i need a list of lua callbacks pls[/quote]

Zhilkin already linked where the lua wizardry is.

[quote=“Zhilkin, post:25, topic:13488”]Check example mods in https://github.com/CleverRaven/Cataclysm-DDA/tree/master/doc/sample_mods

Also all LUA bindings are automatically extracted to https://github.com/CleverRaven/Cataclysm-DDA/blob/master/lua/class_definitions.lua[/quote]

I’ve played a bit with the LUA: http://smf.cataclysmdda.com/index.php?topic=14542.msg300320#msg300320

Will that be enough to prevent LUA from being axed? :slight_smile:

Lua mod that adds two atomic Rivtech tools (entity scanner and earthquake generator):

Whoa, join a game a week after everyone decides to get rid of the one thing that actually caught your interest in the game… O blessed art thou, circumstance. Well, small loss if they go through with it and I disappear, I guess. :stuck_out_tongue_winking_eye:

I get that its support is probably a pain, and indeed so many people are doing things in hard-code. But the problem isn’t that everyone’s doing stuff in the native code and therefore Lua support is irrelevant… the problem is that everyone’s doing stuff in the native code when they shouldn’t. Esoteric, purpose-driven scripting or behaviour should be externalised; the stuff that’s hard-coded in a game should almost always be limited solely to core mechanics and platform support. Things like door pulleys, etc. should be externalised as a matter of best practice. The vast majority of the mapgen stuff is being externalised already, and the only holdouts are, no surprises, scripted functionality.

Lua would also be pretty much essential for NPC behaviour and dialogue, unless one can honestly assert they’re willing to put in the work on a JSON-based solution that could rival, say, Fallout 1’s level of complexity. (Which Black Isle used scripts for, I might add. =)) At the very least, it should be easy to foresee that, once people stop worrying over the gameplay mechanics and start concentrating on the late game, numerous amounts of scripted behaviour will be critical. Lua is the glue that affixes the game to the sandbox. It’s a great sandbox game, but its longevity is limited to an in-game year at best, and the only meaningful way of introducing dungeons, conversations, quests, and unique artifacts will be with a script engine.

“Not being used” as a justification for removal is a self-fulfilling prophecy: it will indeed never get used if you get rid of it. Rather than throwing out the baby with the bathwater, concentrate on showcasing it and discouraging improper use of the engine for stuff that really should be maintained in soft-code. Pretty much every time someone says “I don’t think this should go into the mainline” is a pro for Lua support. =) If you give people actual time to use the functionality it adds, and provide documentation that isn’t as obtuse as raw compiler-generated output, we’ll be more likely to see interesting mods cropping up here (like those of the Japanese community).

[edit]Just saw the thread linked here on Github debunking the “time” part, but wanted to mention the game currently attracts only programmers and sandbox-players because there isn’t an actual plot going on – shift the focus onto a campaign (presumably, downloadable independent campaigns) and you’re far more likely to see writers and designers showing up as well, who will be clamoring for anything that doesn’t require them to get down and dirty with the core code, and yet will be deeply and profoundly disappointed with the limitations of JSON or the (relatively) astronomical turnaround time on requesting engine features needed for their questlines. Thus, my “time” argument is not based on “give it time”, but rather “wait for the time where it becomes relevant”. No one will use the Lua functionality right now because the game just isn’t far enough along for it to matter, but that’s no incentive to get rid of it… that’s incentive to keep it in now so it doesn’t become an absolute bitch to bring back in later. If this game will only ever remain a zombie sandbox, then this of course no longer matters.

That all said, there are more than a few examples of iuse features in those Japanese mods that would make a not-insubstantial number of people pissed if support were removed entirely. =)

Well reasoned argument, but it’s simply not compelling.
I have personally spent dozens to hundreds of hours on LUA support, a number of other very productive developers have spent far more time than me. In addition, LUA support makes builds harder for everyone, representing a drag on the entire project’s productivity. The sum easily represents over a thousand dev-hours of time spent on this feature. The lua bindings themselves are 24,000 lines of C++.
On the other hand, we have what you see listed in this thread, an extremely meagre list of features, that in most cases would have been quicker to develop in C++, totaling something like a few dozen hours worth of development. There’s something like 2,000 lines of LUA that have been written for this project.

This ratio just. does. not. make. sense.

That’s a really hard sell in a project like this, I’m not about to tell people that they MUST code certain things in LUA, regardless of whether they know the language or not. That literally means refusing contributions in some cases.

If we’re talking converting existing functionality to LUA, I’m sure as hell not going to shoulder the overhead of rewriting tens of thousands of lines of code* in a scripting language purely in the name of “correctness”. For that matter, I don’t want to review tens of thousands of lines of LUA code that don’t add functionality to the game, but instead just move it elsewhere.

[quote=“JT, post:37, topic:13488”]Lua would also be pretty much essential for NPC behaviour and dialogue,

Lua is the glue that affixes the game to the sandbox.

the only meaningful way of introducing dungeons, conversations, quests, and unique artifacts will be with a script engine.[/quote]
This assertion doesn’t follow, you can obviously do anything in C++ that you can do in LUA. There is some kind of dynamic in games development where LUA or other scripting languages are preferred over coding things directly in C++, but it just hasn’t surfaced in this project. We seem to have very little LUA expertise, even though a number of people have stated it’s the "right thing to do.

I disagree, we ether have zero interest in writing meaningful features in LUA, or we have deeply disfunctional LUA integration, such that people interested in using it flee in terror immediately. In either case, the solution is to get rid of the disfunctional integration and then bring it back when it is needed AND someone (frankly, not me, I have no idea how that sort of integration should work) has a plan for supporting scripters other than “expose a bunch of internal game state to LUA”. Basic LUA integration is extremely simple (though it does add some complexity to the build process), so it’s fairly trivial to restore, it’s the infrastructure to expose engine internals to LUA that’s a PITA, and that’s what hasn’t proven successful.

*You might think I’m exaggerating, but check the main targets for this. iuse.cpp ~8,000 lines of code, mapgen.cpp ~10,000 lines of code, mapgen_functions.cpp ~5,000 lines of code, iexamine.cpp ~3,500 lines of code, monattack.cpp ~4,500 lines of code.

Gunsmith, water mod is in here:

http://chezzo.com/cdda/mods/Japanese_Mods.zip

It does use Lua, but not to make it a water world, it looks like it uses it to give fish better vision.

[quote=“Kevin Granade, post:38, topic:13488”]That’s a really hard sell in a project like this, I’m not about to tell people that they MUST code certain things in LUA, regardless of whether they know the language or not. That literally means refusing contributions in some cases.
[snip]
If we’re talking converting existing functionality to LUA, I’m sure as hell not going to shoulder the overhead of rewriting tens of thousands of lines of code* in a scripting language purely in the name of “correctness”. For that matter, I don’t want to review tens of thousands of lines of LUA code that don’t add functionality to the game, but instead just move it elsewhere.

*You might think I’m exaggerating, but check the main targets for this. iuse.cpp ~8,000 lines of code, mapgen.cpp ~10,000 lines of code, mapgen_functions.cpp ~5,000 lines of code, iexamine.cpp ~3,500 lines of code, monattack.cpp ~4,500 lines of code.
[snip]
This assertion doesn’t follow, you can obviously do anything in C++ that you can do in LUA. There is some kind of dynamic in games development where LUA or other scripting languages are preferred over coding things directly in C++, but it just hasn’t surfaced in this project. We seem to have very little LUA expertise, even though a number of people have stated it’s the "right thing to do.[/quote]

The stuff that’s being externalised will continue to be externalised and genericised for re-use elsewhere, and I never for a moment suggested that any one person would be expected to shoulder the burden entirely. :wink: I’ve been looking at the mapgen stuff specifically as something I’ve wanted to hop into and start externalising myself, which is hampered mainly by the fact that I would need to get directly involved with the build process too.

The reason that dynamic exists is because of the lean and mean principle: building story mechanics into the main build involves an overhead that can slow or stifle the development process on both sides of the equation, especially in something as mutable as a story. While development is normally iterative, moving from one feature to the next except when feature creep obviates or breaks previous features or bugs are discovered, storywriting is normally recursive, continuously refining, revising, rearranging, deleting, expanding, and distilling existing pieces to build a more cohesive whole. It can of course mimic development closely (and vice versa if there is no check on feature creep), but it’s usually easy to spot those games that have done their stories that way: they usually feel like run-on sentences with one stereotype after the next, rather than archetypes who fit in (or more accurately don’t fit in).

My assertion is that it is indeed necessary and the right thing to do because any kind of direct integration with the program code will naturally suffer from substantial “noise” as every last change is made, re-made, reverted, and re-re-made. I’ll be a lesser man and note that there are three separate implementations of winches in the game engine, one for each of garages, farms, and vault, which is precisely the scenario that a data-based architecture is intended to correct. Okay, this was completely wrong. Could’ve sworn I had seen separate code somewhere…

Essential balance of map generation is another – for instance, the hard-coded one_in(100) for a spiderweb to spawn means that probabilistically, you will encounter at least one after walking through just 23 horizontal tiles of forest, assuming your reality bubble overlaps three map tiles. This could be switched over to externalising that magic number into an option-friendly global variable, or could be turned into its own feature request to refine the probability further, but if the work were done to externalise these sorts of things into their own map tiles without concerning themselves with balance, a balancing and refinement pass could then balance dozens or hundreds of these sorts of things simultaneously in a fraction of the time and overhead.

This divide is also why almost every substantive change I’ve seen in the codebase so far has focused on raw mechanics and refining the existing feature set; it’s not easy or quick to work on balance-, plot-, or mission-related mechanics as both the development and scripting language are oriented towards engine-focused behaviour.

It’s definitely the latter scenario. For instance, every single one of the extant “do one op to all monster types” Lua mods, including even the Ninja mod, uses this:

local monster_types = game.get_monster_types()

This function is not listed in class_definitions.lua or anywhere else in the data. One has to go directly to the C++ code in catalua.cpp to find it.

(Incidentally, the Japanese Elona roguelike is written in a language that is so high-level (Hot Soup Processor) that it’s a borderline scripting language in its own right. I suspect that Japanese modders are thus naturally inclined to use Lua. I also note that it must be jarring to have to switch to a Romantic/Germanic language to program with: to a person knowing a pictographic language, code is quite literally code.)

I’ve heard about how easy Lua is to integrate compared to, say, Python; if it really is that easy then it won’t be a major loss, so long as it can come back in another form later on. It’d render anything I was contemplating moot, but all of that doesn’t even exist yet so it’s a literal zero-value loss (actually even a net benefit to me as it saves me some time, come to think of it, although I’ll lament not being able to do it ;-)).

In the end, and it seems like we’re agreed on this, the difficulty here is that the Lua support for all of its fantastic power is basically just a layer on the game engine which requires direct and intimate knowledge of the program code, because there isn’t enough abstraction and because the totality of its bindings are not actually visible to anyone who’d want to use it. Don’t get me wrong, having the power to affect the game engine so tightly is a godsend in any scripting environment – but it’s not documented meaningfully or in a way that would encourage its use over the game engine itself, and conventions that would apply from other “languages” like the scripts in Bethesda’s Gamebryo incarnations don’t apply here. Thus, anyone who wants to use it will need to refer directly to the program code anyway.

The pragmatists among you have correctly realised that if they have to learn/know C++ to use the Lua support then they might as well just use C++, especially if they don’t also already know Lua. The… let’s call them “lazyists”, like me, would much rather work outside of that environment with rapid prototyping that needs no more than the load time of the game to try. Given the immense popularity of the game on Reddit and those few sites I’ve bumped into that laud it, there’s a substantially low ratio between “devs” and “community” and I suspect that ratio reflects programming ability – many people would contribute if they could, but don’t.

(Granted, the (unsuccessful) VS build I tried took only about three or four minutes to build the object code before it broke at the linking phase, although I’m not sure how much longer it would have chugged on the linker.)


If you do want a candidate for an improved architecture, all you really need is an event-driven system:

  1. Global: Currently already handled with the main.lua in each mod.

  2. Missions: Currently, each “mod” provides a global script and a preloader to attach scripts to iuse actions. Taking a page from Bethesda, it could also be a container for missions that run scripts – each mission could have zero or more scripts attached. Each script attachment would define a turn interval where it would fire, and these scripts would thus heartbeat so long as that mission is in the player’s quest tracker. (Because we don’t have to work around the unique perversions of the Bethesda engines, there’s no need to rely on hidden quests and that sort of nonsense, since we have a built-in global script architecture also.)

  3. Mapgen: Any time a map tile is loaded, check the JSON for that map tile and, if it defines one, fire the main function in the named script. This would make it almost simplistic to externalise the majority of the mapgen code in and of itself.

  4. Item Use: Already functional, although tying scripts to iuse actions more directly (i.e., specifying the filename of the script to run directly in the JSON) would make things cleaner.

  5. Objects: Each object can have zero or more scripts attached, and objects receive heartbeats to fire their scripts which are divided over the total number of loaded script objects to avoid burdening the engine – unless a script is declared mission-critical, where it would fire every turn. (Some common sense conventions like declaring creature objects mission-critical if they happen to be in combat with the player would also make sense.) This would handle Macguffins, scripted movements and scenes, and could even be used to override AI behaviour and control them manually.

There is, for the sake of honesty, one overriding and uncontestable counter-argument to anything I have here: if the game is intended to be a single centralised forum working on a single unified plot, rather than based on a community that contributes its own independent plotlines and featuresets – i.e., a game that is based on creating an idealised singleton rather than a game that is based on catering to individual whims and fancies and creating their own unique flavours – then there is absolutely no benefit to distinguishing a modder versus a developer. It will, unfortunately, limit the game to those modders who are also developers, but that isn’t necessarily a bad thing.

The real Duesy (if implementing Lua later on is a bitch, then this is the name-it-after-my-wife-Dotti) is that any meaningful script system would have to keep certain entities persisting at a low level of fidelity, with periodic script updates, which would involve basically discarding the reality bubble as we know it.

(Out of context, that last part almost sounds like something you’d read on a dark web forum…)