This is the place for discussion and support for LunaLua and related modifications and libraries.
Moderator: Userbase Moderators
Forum rules
Before you make a topic/post, consider the following:
-Is there a topic for this already?
-Is your post on topic/appropriate?
-Are you posting in the right forum/following the forum rules?
|
|
|
|
-
Daring Tombstone
- Blooper

- Posts: 160
- Joined: Mon Aug 28, 2017 10:57 pm
- Flair: What? Not 1000 posts? That means I suck right?
Postby Daring Tombstone » Wed Jun 13, 2018 10:40 pm
I have the bomb rinka set on a layer that appears halfway through the fight then despawns when the boss is finished. It's just one rinka block that isn't set on a generator. Oddly I can place this same rinka anywhere else but as soon as it's boss fight time it has a random chance of causing this error.
Edit: After some tinkering I've noticed the "glitch" rinka doesn't cause any errors but all the other ones do. I might just use this one instead of the "bomb" rinka.
|
|
|
|
|
|
|
|
|
-
ElectriKong
- Bowser

- Posts: 4651
- Joined: Mon Jun 06, 2016 4:32 pm
- Flair: I have NO idea what to put here
- Pronouns: he/him
-
Contact:
Postby ElectriKong » Sat Jun 16, 2018 6:19 pm
MisterZygarde64 wrote: ↑Sat Jun 16, 2018 3:49 pm
Can we use multiple files of Lunalua.txt in one level?
LunaLua.txt is not even a file for this.
You currently call the file lunadll.lua, and there can only be one. You can add as many APIs as is needed though, an load them in the lunadll.lua file.
|
|
|
|
|
|
|
|
|
-
Quantumenace
- Chain Chomp

- Posts: 308
- Joined: Mon Dec 28, 2015 2:17 am
Postby Quantumenace » Sun Jun 17, 2018 2:21 am
Daring Tombstone wrote: ↑Wed Jun 13, 2018 10:40 pm
I have the bomb rinka set on a layer that appears halfway through the fight then despawns when the boss is finished. It's just one rinka block that isn't set on a generator. Oddly I can place this same rinka anywhere else but as soon as it's boss fight time it has a random chance of causing this error.
Edit: After some tinkering I've noticed the "glitch" rinka doesn't cause any errors but all the other ones do. I might just use this one instead of the "bomb" rinka.
Looking at the moarRinkas code for the version included in Beta 3, it has some major oversights, like pausing. Try pausing the game for about 5 seconds when a black Rinka is on the spawner, and have fun dodging that.
The problem here is that it tries to grab all NPCs intersecting the Rinka to get the spawner type of the spawner for every tick during the whole time the Rinka exists, and it doesn't bother filtering out rinka blocks. Then it tries to pnpc wrap all of these NPCs and then check their data.spawnertype field. But pnpc doesn't work on generators, so the data field doesn't exist and can't be indexed.
Long story short, if moarRinkas is loaded, if any rinka intersects any generator it will make Lua crash. The "glitch" rinka might just have a lower chance of touching the generators.
You should be able to fix it by making a custom moarRinkas file, and changing these lines:
Line 108: for g,w in ipairs(spawner) do if w.id == 211 then
Line 186: end end
|
|
|
|
|
|
|
|
|
-
MisterZygarde64
- Bot

- Posts: 52
- Joined: Wed Jun 08, 2016 9:43 pm
Postby MisterZygarde64 » Sun Jun 17, 2018 6:04 pm
Electriking wrote: ↑Sat Jun 16, 2018 6:19 pm
MisterZygarde64 wrote: ↑Sat Jun 16, 2018 3:49 pm
Can we use multiple files of Lunalua.txt in one level?
LunaLua.txt is not even a file for this.
You currently call the file lunadll.lua, and there can only be one. You can add as many APIs as is needed though, an load them in the lunadll.lua file.
Cool also where do we put the files for Raocoin2?
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Sun Jun 17, 2018 7:12 pm
MisterZygarde64 wrote: ↑Sun Jun 17, 2018 6:04 pm
Electriking wrote: ↑Sat Jun 16, 2018 6:19 pm
MisterZygarde64 wrote: ↑Sat Jun 16, 2018 3:49 pm
Can we use multiple files of Lunalua.txt in one level?
LunaLua.txt is not even a file for this.
You currently call the file lunadll.lua, and there can only be one. You can add as many APIs as is needed though, an load them in the lunadll.lua file.
Cool also where do we put the files for Raocoin2?
Copy it into the same folder as your lunadll.lua file, for any library, however raocoin2.lua is really broken and I wouldn't use it
|
|
|
|
|
|
|
|
|
-
MisterZygarde64
- Bot

- Posts: 52
- Joined: Wed Jun 08, 2016 9:43 pm
Postby MisterZygarde64 » Sun Jun 17, 2018 7:32 pm
PixelPest wrote: ↑Sun Jun 17, 2018 7:12 pm
MisterZygarde64 wrote: ↑Sun Jun 17, 2018 6:04 pm
Electriking wrote: ↑Sat Jun 16, 2018 6:19 pm
LunaLua.txt is not even a file for this.
You currently call the file lunadll.lua, and there can only be one. You can add as many APIs as is needed though, an load them in the lunadll.lua file.
Cool also where do we put the files for Raocoin2?
Copy it into the same folder as your lunadll.lua file, for any library, however raocoin2.lua is really broken and I wouldn't use it
I meant do I put the lunadll.lua file with raocoin2.lua in the level folder or episode folder?
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Sun Jun 17, 2018 10:44 pm
MisterZygarde64 wrote: ↑Sun Jun 17, 2018 7:32 pm
PixelPest wrote: ↑Sun Jun 17, 2018 7:12 pm
MisterZygarde64 wrote: ↑Sun Jun 17, 2018 6:04 pm
Cool also where do we put the files for Raocoin2?
Copy it into the same folder as your lunadll.lua file, for any library, however raocoin2.lua is really broken and I wouldn't use it
I meant do I put the lunadll.lua file with raocoin2.lua in the level folder or episode folder?
Level folder for a level
|
|
|
|
|
|
|
|
|
-
lumpman2
- Goomba

- Posts: 4
- Joined: Mon Apr 06, 2015 7:48 pm
Postby lumpman2 » Mon Jun 18, 2018 7:04 pm
I'm trying to start out with some basic code using LunaLua, but I don't know what to use to start. I've tried using the PGE Editor inside the SMBX2 folder (inside a levels folder I have a luaTest folder with a lunadll.lua inside of it), but when I insert code into the lua file and test the level the code doesn't appear to work.
I tried using this code:
Code: Select all function onLoop() printText("PLAYER x="..tostring(player.x).." y="..tostring(player.y), 30, 60) end
and testing the level from the PGE editor and no such text is on screen.
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Mon Jun 18, 2018 7:29 pm
lumpman2 wrote: ↑Mon Jun 18, 2018 7:04 pm
I'm trying to start out with some basic code using LunaLua, but I don't know what to use to start. I've tried using the PGE Editor inside the SMBX2 folder (inside a levels folder I have a luaTest folder with a lunadll.lua inside of it), but when I insert code into the lua file and test the level the code doesn't appear to work.
I tried using this code:
Code: Select all function onLoop() printText("PLAYER x="..tostring(player.x).." y="..tostring(player.y), 30, 60) end
and testing the level from the PGE editor and no such text is on screen.
I'm a little confused as to what your set-up is. Make sure to have the lunadll.lua file in your level's custom graphics folder; a folder with the same name as the .lvl file (but not with the .lvl at the end), which should be in the same directory.
Make sure that you're testing through LunaTester (F5) and not the PGE Alpha Tester.
Also try to avoid using deprecated functions. You should use onTick instead of onLoop and Text.print instead of printText
|
|
|
|
|
|
|
|
|
-
lumpman2
- Goomba

- Posts: 4
- Joined: Mon Apr 06, 2015 7:48 pm
Postby lumpman2 » Mon Jun 18, 2018 7:55 pm
PixelPest wrote: ↑Mon Jun 18, 2018 7:29 pm
lumpman2 wrote: ↑Mon Jun 18, 2018 7:04 pm
I'm trying to start out with some basic code using LunaLua, but I don't know what to use to start. I've tried using the PGE Editor inside the SMBX2 folder (inside a levels folder I have a luaTest folder with a lunadll.lua inside of it), but when I insert code into the lua file and test the level the code doesn't appear to work.
I tried using this code:
Code: Select all function onLoop() printText("PLAYER x="..tostring(player.x).." y="..tostring(player.y), 30, 60) end
and testing the level from the PGE editor and no such text is on screen.
I'm a little confused as to what your set-up is. Make sure to have the lunadll.lua file in your level's custom graphics folder; a folder with the same name as the .lvl file (but not with the .lvl at the end), which should be in the same directory.
Make sure that you're testing through LunaTester (F5) and not the PGE Alpha Tester.
Also try to avoid using deprecated functions. You should use onTick instead of onLoop and Text.print instead of printText
Thank you, this finally worked. I had everything set up correctly before, and some other code I wrote myself was using the correct functions, but I just wasn't using the LunaTester.
|
|
|
|
|
|
|
|
|
-
Daring Tombstone
- Blooper

- Posts: 160
- Joined: Mon Aug 28, 2017 10:57 pm
- Flair: What? Not 1000 posts? That means I suck right?
Postby Daring Tombstone » Wed Jun 20, 2018 1:57 am
Quantumenace wrote: ↑Sun Jun 17, 2018 2:21 am
Looking at the moarRinkas code for the version included in Beta 3, it has some major oversights, like pausing. Try pausing the game for about 5 seconds when a black Rinka is on the spawner, and have fun dodging that.
The problem here is that it tries to grab all NPCs intersecting the Rinka to get the spawner type of the spawner for every tick during the whole time the Rinka exists, and it doesn't bother filtering out rinka blocks. Then it tries to pnpc wrap all of these NPCs and then check their data.spawnertype field. But pnpc doesn't work on generators, so the data field doesn't exist and can't be indexed.
Long story short, if moarRinkas is loaded, if any rinka intersects any generator it will make Lua crash. The "glitch" rinka might just have a lower chance of touching the generators.
You should be able to fix it by making a custom moarRinkas file, and changing these lines:
Line 108: for g,w in ipairs(spawner) do if w.id == 211 then
Line 186: end end
I actually didn't notice pausing the game would do that to the rinkas (since I didn't pause during testing). I did try the fix you suggested but it still didn't seem to work for me. I won't be using moarRinkas anyways since someone could always pause the game unknowingly then come back five minutes later to a screen full of death. Appreciate the effort to help though.
|
|
|
|
|
|
|
|
|
-
MegaCDFan235
- Tweeter

- Posts: 135
- Joined: Sun Nov 15, 2015 5:33 pm
-
Contact:
Postby MegaCDFan235 » Wed Jun 20, 2018 3:47 pm
Code: Select all local loognpc = NPC.get(101)[1]
function onStart()
loognpc:mem(0x44, FIELD_BOOL)
loognpc:mem(0x00, FIELD_STRING)
end
function onEvent(illegal2)
if loognpc:mem(0x44, FIELD_BOOL) == 1 then
if loognpc:mem(0x00, FIELD_STRING) == "luigi1.exe" then
player.character = CHARACTER_MEGAMAN
end
end
end
end
This code gives me this error:
but without the last "end" gives me this one:
What am I doing wrong here? (What's supposed to happen is that when you approach a Luigi in the layer labelled "luigi1.exe" (without the quotation marks), it will check for if it is activated and the layer name, and if every value is correct, the player will become Mega Man)
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Wed Jun 20, 2018 9:34 pm
The first error is a syntax error which prevents the code from running at all. The second error is the result of a nil value, which means that at least part of the code has run up to that point. Your code which produces the second error is almost correct, you just need to set the value for loognpc in onStart instead of at the beginning. NPCs, players, etc. aren't accessible until onStart, and before then, NPC.get(101) is just returning an empty table
|
|
|
|
|
|
|
|
|
-
Emral
- Cute Yoshi Egg

- Posts: 9886
- Joined: Mon Jan 20, 2014 12:58 pm
- Flair: Phoenix
Postby Emral » Fri Jun 22, 2018 8:29 am
PixelPest wrote: ↑Wed Jun 20, 2018 9:34 pm
The first error is a syntax error which prevents the code from running at all. The second error is the result of a nil value, which means that at least part of the code has run up to that point. Your code which produces the second error is almost correct, you just need to set the value for loognpc in onStart instead of at the beginning. NPCs, players, etc. aren't accessible until onStart, and before then, NPC.get(101) is just returning an empty table
PixelPest your explanation is embarassingly bad.
1) Care to explain "<eof> expected near end"? Might've been some LunaLua General Help if you did.
<eof> is the error window's way of saying "end of file". So the error "<eof> expected near end" reads as "I found an 'end' statement when I was expecting the file to end", which explains why removing the last "end" fixed it.
These errors are pretty easy to avoid with proper indenting. You're doing a pretty good effort in your code, but it falls apart a bit in the onEvent function.
To be precise: After the line
Code: Select all if loognpc:mem(0x00, FIELD_STRING) == "luigi1.exe" then
you seem to indent twice, and then indent back by one for the next end, as you should. But as you can see in your post, the "if" and its "end" don't line up, leading to a jarring gap between the third- and second-to-last "end"s in the code.
This might've happened because the code was written with a mix of spaces and tabs for indenting (the lengths of each indent is inconsistent). It's pretty easy to keep track of indents if you press tab once whenever you wanna move in, and press backspace whenever you wanna move out by one. Here's a comparison of your indenting and proper one, for visualisation:
Code: Select all local loognpc = NPC.get(101)[1]
function onStart()
loognpc:mem(0x44, FIELD_BOOL)
loognpc:mem(0x00, FIELD_STRING)
end
function onEvent(illegal2)
if loognpc:mem(0x44, FIELD_BOOL) == 1 then
if loognpc:mem(0x00, FIELD_STRING) == "luigi1.exe" then
player.character = CHARACTER_MEGAMAN
end
end
end
end
Code: Select all local loognpc = NPC.get(101)[1]
function onStart()
loognpc:mem(0x44, FIELD_BOOL)
loognpc:mem(0x00, FIELD_STRING)
end
function onEvent(illegal2)
if loognpc:mem(0x44, FIELD_BOOL) == 1 then
if loognpc:mem(0x00, FIELD_STRING) == "luigi1.exe" then
player.character = CHARACTER_MEGAMAN
end
end
end
Note how easy it is to imagine a vertical line from the "if"s to their corresponding "end"s. Making sure that these always line up should make identifying, fixing and avoiding the <eof> error in the future easier.
Back to PixelPest's explanation:
2) You don't point out that MegaCDFan235 uses onEvent wrong.
onEvent isn't supposed to have its argument filled in. To clarify:
"eventName" is a variable which contains a string whenever ANY event is called. There can only be one onEvent per lua file, which will handle all events.
For example, if the event you wanna watch for is called "myEvent", you would check for it like this:
Code: Select all function onEvent(eventName)
if eventName == "myEvent" then
--do stuff
end
end
Back to PixelPest:
3) While your explanation here is sound, the original approach to the problem is way wrong. Did you forget that the NPC array reshuffles? Grabbing a vanilla npc reference in the first frame is bound to error a few frames later.
There are a few ways to fix this, MegaCDFan235:
1. You can load the pnpc library to grab a persistent reference of your npc. Here's an example:
Code: Select all local pnpc = API.load("pnpc")
local myNPC
function onStart()
local firstNPC = NPC.get(101)[1]
myNPC = pnpc.wrap(firstNPC)
end
After the pnpc.wrap line you will be able to use myNPC as a persistent reference. However, the reference will persist if the NPC dies and won't work if the NPC is a generator. Grabbing the first NPC in a table is generally a bit unsafe as soon as you have more than one. Not a problem in this situation, but it's something to watch out for.
2. You can load the NPC in onEvent directly.
Code: Select all function onEvent(eventname)
if eventName == "illegal2" then
local luigi = NPC.get(101)[1]
if luigi.layerName == "luigi1.exe" then
--do stuff
end
end
end
The NPC won't expire while you're in onEvent, usually. So doing this is safer than trying to store a reference across frames.
luigi.layerName contains the same value as luigi:mem(0x00, FIELD_STRING) btw. It's easier to work with, though.
I don't quite know what "When the player approaches Luigi" means, but I'm guessing it means "when the player talks to luigi", because as far as I know 0x44 is the offset for when the exclamation mark is displayed, and I think the illegal2 event would run when talking to Luigi then. If this is the case, there's an even easier way to handle all this:
3. You can use onMessageBox(eventObj, messageName) if this event happens when talking to the NPC:
Code: Select all function onMessageBox(eventObj, messageName)
if (messageName == "luigiTalk") then
eventObj.cancelled = true
Text.showMessageBox("Luigi: You are MegaMan now!")
player.character = CHARACTER_MEGAMAN
end
end
Let's run through this real quick:
onMessageBox runs just before ANY talk message appears on screen. It passes the event of the message appearing, as well as the contents of the message.
Code: Select all if (messageName == "luigiTalk") then
If you set your Luigi NPC to say "luigiTalk", that message will passed to onMessageBox in the messageName argument and the code within this if statement will run.
This cancels the eventObj. This means that the act of showing the message will be cancelled. In short: The message "luigiTalk" will not appear on screen if this line runs.
Code: Select all Text.showMessageBox("Luigi: You are MegaMan now!")
Since Luigi's vanilla message is a placeholder in this method, you can use showMessageBox to show an alternative message. Only if you want, though. This line is optional.
If you have any further questions about any part of this admittedly long explanation, don't hesitate to ask. I tried to make it as easily understandable as possible, but I wouldn't be surprised if I slipped up one way or another.
|
|
|
|
|
|
|
|
|
-
Daring Tombstone
- Blooper

- Posts: 160
- Joined: Mon Aug 28, 2017 10:57 pm
- Flair: What? Not 1000 posts? That means I suck right?
Postby Daring Tombstone » Tue Jun 26, 2018 1:38 am
I'm attempting to give the boss Mouser more than 4 hits by using this code. Code: Select all function onTick()
for k,v in pairs(NPC.get(211,player.section)) do
v:mem(0x148,FIELD_WORD,10)
end
end
Obviously it's wrong. It doesn't give me an error but I'm assuming this isn't the way to do this properly. If it's too difficult I don't need to give the boss more hits. Honestly it's more about learning a little bit of lua.
|
|
|
|
|
|
|
|
|
-
PixelPest
- Link

- Posts: 7111
- Joined: Sun Jul 12, 2015 5:38 pm
- Flair: Tamer of Boom Booms
-
Contact:
Postby PixelPest » Tue Jun 26, 2018 7:36 am
The way the HP memory field works is that it counts up, jumping on a boss makes it go up by three, fireball probably up one, etc. until it reaches a certain value
The Lua code itself has proper syntax and all, the logic is just wrong. If you want to increase a boss's HP set it to a low number, like -21, -24, etc. Also if you keep setting it in onTick the boss will never be able to be killed. I'd remove the section parameter from NPC.get so you loop over all Mousers in the entire level instead of in the player's section, and put this code in onStart so that it only runs once at the beginning of the level
|
|
|
|
|
|
|
|
|
-
Daring Tombstone
- Blooper

- Posts: 160
- Joined: Mon Aug 28, 2017 10:57 pm
- Flair: What? Not 1000 posts? That means I suck right?
Postby Daring Tombstone » Tue Jun 26, 2018 5:06 pm
Okay thanks for the reply. I've changed it to this code.
Code: Select all function onStart()
for k,v in pairs(NPC.get(262)) do
v:mem(0x148,FIELD_WORD,-36)
end
end
In my last code the npc id was 211 because it was 2 am and 262 looked like 211 for some reason (262 is the actual mouser id). It still doesn't seem to function correctly for me. So something else is off with it. Appreciate the help. If it affects anything, the mouser spawns in via a generator to simulate it coming through a pipe.
|
|
|
|
|
|
|
|
|
-
Hoeloe
- Phanto

- Posts: 1465
- Joined: Sat Oct 03, 2015 6:18 pm
- Flair: The Codehaus Girl
- Pronouns: she/her
Postby Hoeloe » Tue Jun 26, 2018 5:42 pm
Daring Tombstone wrote: ↑Tue Jun 26, 2018 5:06 pm If it affects anything, the mouser spawns in via a generator to simulate it coming through a pipe.
If it spawns in via generator, the mouser doesn't exist when onStart is called. onStart is only run once when the level starts. If the mouser doesn't exist at that point, obviously it won't be affected.
|
|
|
|
|
|
|
|
|
-
Daring Tombstone
- Blooper

- Posts: 160
- Joined: Mon Aug 28, 2017 10:57 pm
- Flair: What? Not 1000 posts? That means I suck right?
Postby Daring Tombstone » Tue Jun 26, 2018 8:30 pm
Hoeloe wrote:
If it spawns in via generator, the mouser doesn't exist when onStart is called. onStart is only run once when the level starts. If the mouser doesn't exist at that point, obviously it won't be affected.
Ah okay. I wasn't aware setting npc codes wouldn't work in this scenario. I was in the mindset that it would just set the hits even if it didn't exist at that particular moment. Thank you for pointing that out. Hope you all have a great day.
|
|
|
|
|
Return to “LunaLua”
Users browsing this forum: No registered users and 2 guests
|