Duke4.net Forums: Lunatic -- Lua for EDuke32 [preview introduction] - Duke4.net Forums

Jump to content

  • 3 Pages +
  • 1
  • 2
  • 3
  • You cannot start a new topic
  • You cannot reply to this topic

Lunatic -- Lua for EDuke32 [preview introduction]  "The moon has come around!"

User is offline   Hendricks266 

  • Weaponized Autism

  #61

View PostJames, on 26 December 2013 - 12:50 PM, said:

Too bad for those of us that still use CON and don't have the time to learn LUA though, he said that he wasn't keen on adding any more CON commands :wub:

I'm not past adding new CON commands, but they need a good purpose.
0

User is offline   Jblade 

#62

View PostKyle873, on 26 December 2013 - 01:43 PM, said:

Lua is a very simple to learn language I think, if you're familiar with any other programming languages you should be able to pick it up fairly quickly.

I'm not, CON's main appeal was that I didn't need to know programming to use it. All of the examples and stuff so far in this topic are completely foreign to me. It doesn't matter in anycase, since CON will always be around in some form. I just don't have the time to learn a complicated language these days.

Quote

I'm not past adding new CON commands, but they need a good purpose.

Well that's good to hear, but from what I understand (unless I've missed something) the new stuff added to make new breakable lights is lua only.
0

User is offline   The Commander 

  • I used to be a Brown Fuzzy Fruit, but I've changed bro...

#63

I haven't even looked at the LUA code for this, but this is the kind of LUA coding I am use to in Garry's Mod

function pSpawn(ply)
	local decider = math.random(1,5)
	if decider == 1 then ply:SetPos(Vector(-1809.119019,-5081.286621,151.301315)) end
	if decider == 2 then ply:SetPos(Vector(-1849.182983,-4930.058594,140.910019)) end
	if decider == 3 then ply:SetPos(Vector(-2011.731445,-4952.591797,146.132523)) end
	if decider == 4 then ply:SetPos(Vector(-1728.267944,-5109.243652,129.985275)) end
	if decider == 5 then ply:SetPos(Vector(-1580.698730,-5029.461426,114.260880)) end
end
hook.Add( "PlayerSpawn", "customspawn", pSpawn )


What this does is that it overrides the default spawn points in a source map being run on Garry's Mod and respawns the player at one of the five positions listed above.

This post has been edited by The Commander: 26 December 2013 - 07:33 PM

0

User is offline   Hendricks266 

  • Weaponized Autism

  #64

View PostJames, on 26 December 2013 - 02:10 PM, said:

I'm not, CON's main appeal was that I didn't need to know programming to use it.

CON taught me programming, though now that I know C I can say I've become a much better CON coder for it.

What can be said about CON is that it is lexically simple. Whereas C has a number of operators and constructions, CON has endless variants of "addvar" and whatnot that follow the same pattern. This is likely because anything more complicated would have taken too much time, effort, or skill to write. Keep in mind that CON may have been Todd Replogle's baby. I have no evidence that it was ever intended by 3DR's higher-ups for the game to be so moddable. In fact, being so locked-down shot SW in the foot. [Feel free to correct me if anyone has evidence.]

Lua may take an investment of time to learn. But it is beyond CON's wildest dreams.
1

User is offline   Helixhorned 

  • EDuke32 Developer

#65

View PostFox, on 26 December 2013 - 01:39 PM, said:

To be more specific, for the hitscan command you put the difference beetween the x y z of your initial position to your final position (...).

Yeah, you can phrase it that way -- if there's a specific target position, then the ray vector is the difference between that and the source position. You have to be a little cautious not to pass values too large in magnitude to hitscan(), since like all engine functions it does its calculations in integer arithmetic. Unless you know that the vector must be "short", normalizing some kind of its "length" (e.g. Euclidean, Manhattan or max-norm) to 16384 seems sensible.

View PostJames, on 26 December 2013 - 12:50 PM, said:

Too bad for those of us that still use CON and don't have the time to learn LUA though, he said that he wasn't keen on adding any more CON commands :wub:

I'll try to address your main concern later, but note that while I have no plans to add new game-time commands to CON, I'm certainly interested in improving from the C-CON implementation and prodiving better diagnostics to expose issues in existing CON code. A few examples, by no means exhausitve:

- from lunatic/test/animatesprites.con:
    // This blows up on C-CON:
    getzrange sprite[pi].x sprite[pi].y sprite[pi].z player[THISACTOR].cursectnum
     /*out:*/ ceilz ceilhit florz florhit
      /*in:*/ 128 CLIPMASK0

Generally speaking, LunaCON has been designed from the start with the intention that CON code must not invoke erratic behavior (such as that which could lead to a crash) under any circumstance. Various other examples of code crashing the C-CON implementation are available.

- Adding convenience where appropriate. From the LunaCON manual:

Quote

The redefinequote command can be issued even if the given quote number has not been previously allocated using the definequote directive. This makes it possible to use a range of quote numbers on the fly without the need to declare their future use [up-front].


- Cleaning up some problems with the language that were never identified with C-CON, such as lexical ambiguity: is "1267AT" a label or a number? SST TC uses it as the latter, but in CON, that's a perfectly fine label too (usually, programming languages require identifiers to start with a non-digit).
1

User is offline   Hendricks266 

  • Weaponized Autism

  #66

I remember way back on 3DR, someone had an issue with defineprojectile not liking their label that started with '5'.
0

#67

Question: will lua/Lunatic have the ability to allow changing of music tracks mid-game/level? Specfically like commands to memorize the last used track, one to replay said remembered track, commands for changing the track itself, or even the ability to define custom-labeled tracks that aren't just meant to be used as the defaults for each level [like labeling some themes for battles against bosses, or large hordes of enemies, or one for having to deal with a perilous situation, etc]?
0

User is offline   Mblackwell 

  • Evil Overlord

#68

... ?

http://wiki.eduke32....wiki/Starttrack

(Lunatic supports/will support everything CON does)
0

User is offline   Kyle873 

#69

View PostMblackwell, on 30 December 2013 - 02:20 PM, said:

... ?

http://wiki.eduke32....wiki/Starttrack

(Lunatic supports/will support everything CON does)


I think what he's asking for is more fine-grained control over it. Loading your own files maybe by name and whatnot as opposed to those bound to specific levels.
0

User is offline   Hendricks266 

  • Weaponized Autism

  #70

^I've been stewing over better music commands as part of the EDuke32 Winter of Code... which I haven't started yet. =B
0

User is offline   Helixhorned 

  • EDuke32 Developer

#71

View PostThe Commander, on 26 December 2013 - 07:31 PM, said:

I haven't even looked at the LUA code for this, but this is the kind of LUA coding I am use to in Garry's Mod
function pSpawn(ply)
        local decider = math.random(1,5)
        if decider == 1 then ply:SetPos(Vector(-1809.119019,-5081.286621,151.301315)) end
        if decider == 2 then ply:SetPos(Vector(-1849.182983,-4930.058594,140.910019)) end
        if decider == 3 then ply:SetPos(Vector(-2011.731445,-4952.591797,146.132523)) end
        if decider == 4 then ply:SetPos(Vector(-1728.267944,-5109.243652,129.985275)) end
        if decider == 5 then ply:SetPos(Vector(-1580.698730,-5029.461426,114.260880)) end
end
hook.Add( "PlayerSpawn", "customspawn", pSpawn )

What this does is that it overrides the default spawn points in a source map being run on Garry's Mod and respawns the player at one of the five positions listed above.

I find this bad style because you codify something that's not interesting enough to be code, namely merely data. As a consequence, the code is also more redundant than necessary. Consider this rewrite:

local spawnPositions = {
	{ -1809.119019, -5081.286621, 151.301315 },
	{ -1849.182983, -4930.058594, 140.910019 },
	{ -2011.731445, -4952.591797, 146.132523 },
	{ -1728.267944, -5109.243652, 129.985275 },
	{ -1580.698730, -5029.461426, 114.260880 },
}

local function pSpawn(ply)
	local decider = math.random(1, #spawnPositions)
	ply:SetPos(Vector(spawnPositions[1], spawnPositions[2], spawnPositions[3]))
end

hook.Add("PlayerSpawn", "customspawn", pSpawn)


Besides being a lot nicer to look at, its runtime is also is also independent of the number of spawn positions (for an abstract performance model not taking into account real-wordly stuff such as CPU caches, etc.). It may not matter in this particular case, but for functions run in a tight loop, it could be significant. Incidentally, long if/if-else cascades are also something you often see in CON code.



View PostJames, on 26 December 2013 - 02:10 PM, said:

I'm not, CON's main appeal was that I didn't need to know programming to use it. All of the examples and stuff so far in this topic are completely foreign to me. It doesn't matter in anycase, since CON will always be around in some form. I just don't have the time to learn a complicated language these days.

What are the characteristics of a language by which you consider it 'programming' or not? From a bird's eye view, Lua and CON aren't that different: both are based on a sequential model of computation, both are imperative. Sure, there are advanced concepts... but you don't need to know all of Lua to make good use of it. Let's look at a snippet I posted a while ago, prefixed with line numbers. I claim that you almost don't need to have had prior exposure to programming at all to understand it (but assuming you know what a Build map contains).

 1    for w=0,gv.numwalls-1 do
 2        local wal = wall[w]
 3        if (wal.overpicnum == D.W_FORCEFIELD or wal.overpicnum == D.W_FORCEFIELD+1) then
 4            if (wal.lotag==34) then
 5                if (wal.cstatbits:test(85)) then  -- cstat has any of the bits 64+16+4+1 set?
 6                    wal.cstat = 0
 7                else
 8                    wal.cstat = 85
 9                end
10            end
11        end
12    end


Commenting the non-obvious parts:

- Line 1 contains a loop over the indices of all walls in the currently loaded map. Each iteration of the loop, 'w' takes on a value from 0 to the numebr of walls minus one, in sequence.

- In line 2, a reference to a wall object is stored into a variable named 'wal'. The variable has local scope: it can be referred to up to the 'end' at line 12 closing the generic 'for', and it is said to go out of scope thereafter. Because the variable 'wal' stored a reference to the w'th wall (and not, say, a copy of it), you can use it to both read from and write to the original object, wall[w].

- Line 5 may be slightly unusual. As the comment says, it checks whether the wall's cstat has any the bits in {64, 16, 4, 1} set. In CON, this would be written as
    getwall[w].cstat tmp
    ifand tmp 85
    {
        // ...
    }

In Lunatic, you can also access wal.cstat, but some convenience is provided for carrying out bitwise operations on such members: .cstatbits lets you query or operate on .cstat without calling bitwise functions directly (in Lua, there are no bitwise operators). The ':' syntax can be though of a method invocation on 'wal.cstatbits'. Methods are like functions, but "tied to" a particular object. I'm being vague here... maybe someone else can explain it better.

- Becuase of the semantics of Lua's 'or' and 'and' operators, lines 5 to 9 can be collapsed into
                wal.cstat = (wal.cstatbits:test(85)) and 0 or 85

Nice, huh?


View PostJames, on 26 December 2013 - 02:10 PM, said:

Well that's good to hear, but from what I understand (unless I've missed something) the new stuff added to make new breakable lights is lua only.

Actually, EVENT_DAMAGEHPLANE also runs in CON, from both C-CON and LunaCON builds, but its interface (how to decode passed RETURN, what values to provide to RETURN on leaving) is undocumented. The question is: why would you want to write a DAMAGEHPLANE event in CON? Two reasons you'd not:

- In Lunatic, you can have a reference to an object that is a "ceiling-or-floor". That is, if you want some code to run for both ceilings and floors, you don't need to duplicate it, once with sector[].ceiling* accesses and the other one with sector[].floor* ones. Less redundancy: good.

- EVENT_DAMAGEHPLANE receives in RETURN a value that encodes which part (ceiling or floor) of what sector was hit. But it also examines RETURN after the event has left. If you chain multiple events, there's no way to obtain the original, passed value of RETURN from a second DAMAGEPLANE event once the first one has modified it (to signal the action to take). In Lunatic, a trick is used: RETURN is also passed in the 'dist' argument. In CON, it can't be queried directly, but only compared for inequality against a number with ifdistl/ifdistg.
The ability to chain this event means that you can code each hplane-breaking effect independently. This is shown in test/damagehplane.lua: the code for TROR-bunch glass breaking and the new breakable ceiling picnums live in two separate event definitions. So, if the event is properly written, you can provide a stand-alone mutator merrily working together with other DAMAGEHPLANE events.
1

User is offline   Helixhorned 

  • EDuke32 Developer

#72

View PostHelixhorned, on 01 January 2014 - 07:10 AM, said:

Consider this rewrite:

Oops, the 'pSpawn' function should read

function pSpawn(ply)
	local decider = math.random(1,5)
	ply:SetPos(Vector(spawnPositions[decider][1], spawnPositions[decider][2], spawnPositions[decider][3]))
end


or, caching the 'spawnPositions[decider]' subexpression into a temporary local,

function pSpawn(ply)
	local decider = math.random(1,5)
        local pos = spawnPositions[decider]
	ply:SetPos(Vector(pos[1], pos[2], pos[3]))
end



The LuaJIT author notes that manual common subexpression elimination (CSE) such as in the second version can be counter-productive, but I prefer it stylistically.

Mike Pall said:

* Do not try to second-guess the JIT compiler.
- It's perfectly ok to write 'z = x[a+b] + y[a+b]'.
- Do not try CSE by hand, e.g. 'local c = a+b'.

1

User is offline   The Commander 

  • I used to be a Brown Fuzzy Fruit, but I've changed bro...

#73

View PostHelixhorned, on 01 January 2014 - 09:40 AM, said:

Oops, the 'pSpawn' function should read

function pSpawn(ply)
	local decider = math.random(1,5)
	ply:SetPos(Vector(spawnPositions[decider][1], spawnPositions[decider][2], spawnPositions[decider][3]))
end


Heh, I saw that and thought that is not going to work as a local on server side code and had already fixed it. :wub:

But yes, this format is much cleaner than what I had and will make any more spawns I need to add just that tiny bit easier.
Originally I only had 1 spawn point and after the map restarts everyone spawn and stacks on top of each other, makes for a nice looking totem pole.

I myself am still learning this LUA code and am picking it up slowly, mostly from looking at other code and seeing how it functions.

EDIT: Learning from other code I have managed to the save players table data (inventory, exp, etc) from ugly flat file .txt to a sqllite database which as we know is a lot more efficient.

EDIT 2: @James, I know my LUA isn't Duke based, but I can tell you that when I first looked at LUA, it was like opening up a CON file for the very first time, daunting at first but I know you will be able to pick this up very quickly.

This post has been edited by The Commander: 01 January 2014 - 10:18 AM

0

User is offline   Helixhorned 

  • EDuke32 Developer

#74

If you're curious about palettes, shade tables, the problem of emulating classic visibility in the OpenGL modes and the like, you might be interested in r4423's Lunatic Mapster32 build. It now includes a menu, opened with [;]+[F] in 2D mode, that can be populated from Lua. I hooked up and documented the functions from test/shadexfog.lua to this system. When I'll be writing more about r_usenewshading 3, I may be referring to these.
1

#75

Okay I have no idea if this thread is still the one to use for Lunatic, but I'd like to ask a question. I noticed that Lua's io module isn't present, is it possible that at least io.open and io.read could be added, even if they're only limited to files within the eduke directory?
0

User is offline   Helixhorned 

  • EDuke32 Developer

#76

View PostTheZombieKiller, on 18 January 2016 - 05:30 AM, said:

Okay I have no idea if this thread is still the one to use for Lunatic, but I'd like to ask a question. I noticed that Lua's io module isn't present, is it possible that at least io.open and io.read could be added, even if they're only limited to files within the eduke directory?

Yes, this is the right thread. A safety limitation like you describe is the intent. However, I have no free time to continue developing Lunatic.
0

User is offline   Micky C 

  • Honored Donor

#77

Is this a temporary thing or for the foreseeable future? :thumbsup:
0

User is offline   Hendricks266 

  • Weaponized Autism

  #78

Lunatic people: We now have Lunatic building in C++ mode, and I issued the BUILD_LUNATIC command to Synthesis. Please let me know if this new build introduces regressions in your mods.
2

User is offline   Micky C 

  • Honored Donor

#79

Thanks for all the recent work Hendricks. Is the executable in 5999 a lunatic build? I can't see anything different about the download.
0

User is offline   Hendricks266 

  • Weaponized Autism

  #80

5999 is not a Lunatic build, and I don't know why 6007 didn't show up. >_>
0

User is offline   Hendricks266 

  • Weaponized Autism

  #81

After some manual intervention on TX's part, 6007 is now built.
1

User is offline   Micky C 

  • Honored Donor

#82

Doesn't work with the AMC TC; con code issues apparently.

http://pastebin.com/HqpHfueK
0

User is offline   Hendricks266 

  • Weaponized Autism

  #83

I should have mentioned: Lua mods. I don't expect anything advanced using CON to work, especially anything that uses recent additions to the language which I may not have ported to LunaCON yet.
0

#84

So does this mean Lunatic is somewhat alive again?
0

User is offline   Hendricks266 

  • Weaponized Autism

  #85

No, just that it's not getting left behind.
3

Share this topic:


  • 3 Pages +
  • 1
  • 2
  • 3
  • You cannot start a new topic
  • You cannot reply to this topic


All copyrights and trademarks not owned by Voidpoint, LLC are the sole property of their respective owners. Play Ion Fury! ;) © Voidpoint, LLC

Enter your sign in name and password


Sign in options