PDA

View Full Version : New to Novashell and LUA: need some help



rabidwolf9
08-08-2010, 10:54 PM
I've been around the Dink scene for over 6 years and now that novashell seems to be new thing; I'm going for it. Why? More functionality (hated those Dink limitations) and pretty much to broaden my horizons. Well in any case I hope what I've learned in Dink will prove to help rather than hinder me as I try to make connections between the two and figure out how this new system works and try to make a Dink-like mod in the process.

(1) First question is about graphics. Now I've implemented every static graphic from Dink. The animated ones are the ones I'm semi-confused on. Now if I understand it correctly, what's mainly going on is that animated graphics are going in the scripts directory (to make the filepath easier to find for scripting purposes?), but they don't show up under import graphics because it's not in the maps directory. This could be a problem for some graphics like the blood sequence, because it's often used as a static graphic in modding. So obviously, that wouldn't need a script and in some cases it would need to be in a layer other than entity. So how would I place it like so?

(2) Another question pertaining to graphics. I've implemented the golden heart from Dink using the coin from Topdown RPG as a template. I was able to make it animate, but it looks weird because it's meant to play through and then reverse. How can this be accomplished in Novashell?

(3) I seem to have a problem grasping how variables work in NS. I need some explanation :sweatdrop:

(4) Identification of the player. Say I want the player to say 'hello there'. Obviously I would do it like this GetTextManager:Add("hello there.", ent); if it was run from OnAction(ent) or use this if it was run from the player's script itself. But if those aren't available, I need some other way of IDing him. How does that work?

(5) A little camera trouble.. So I figured out by research I can make the camera halt by using GetCamera:SetEntityTrackingByID(C_ENTITY_NONE);. That works, but about setting it back.. I can't figure that one out.

(6) Lastly, I have a problem with said heart's script which I do find odd seeing how I copied most of the code from the coin (again). He just seems to walk right through it without the oncollision function happening. It may be worth noting that I'm using the scripts from the Dink demo as well. Oh and I set the player's category so he'd walk through it.



function OnInit()

this:SetVisualProfile("~/heart_gold.xml", "heart_gold");
this:LoadCollisionInfo("~/heart_gold.col");

this:SetCollisionCategory(C_CATEGORY_PLAYER, false); //let the player walk through us

m_bPickedup = false;
end

function OnAction(ent)

GetTextManager:Add("It's a golden heart.", ent);
end


function OnCollision(vPosition, vVelocity, vNormal, depth, materialID, entity, state)


if (m_bPickedup == true) then
//already picked up
return;
end

GetTextManager:Add("Yeah, extra life!.", ent);

m_bPickedup = true;
//Let's disappear, we got picked up
this:GetBrainManager():Add('FadeOutAndDelete','fad e_speed_ms=50');

//GetSoundManager:Play("audio/effects/coin.ogg");

//money = entity:Data():ModNum("Money", 1);
//entity:RunFunction("UpdateGUI");
//GetTextManager:Add("I picked up a coin. (" .. tostring(money) .. ")", entity );

end


Now some things that I'm sure are above my head (for now), but want eventually. If someone could help with these, it would be a awesome to have in the long run.

-Pushing:
The big one that scares me. And kind of a necessity for Dink. Would work the same as in dink or zelda.. if the player is against the wall or whatever, he'll play a push animation and that would call some push function on the affected sprite. I'm not even sure how that would work.

-Camera boundaries:
When the player gets towards the edge of the map, the camera should stop following the player at a certain point. I hope that's clear. It's like when he gets to the edge of a cliff, instead of the camer showing all the way down, it will stop before then and the player will move away from the center of the screen.

Thanks to anyone who reads this (apologies for it being soo long). Any help is appreciated even if you can only help with one or two of my problems :D

Seth
08-09-2010, 04:57 AM
Hi,

I'll try to answer these.


(1) First question is about graphics. Now I've implemented every static graphic from Dink. The animated ones are the ones I'm semi-confused on. Now if I understand it correctly, what's mainly going on is that animated graphics are going in the scripts directory (to make the filepath easier to find for scripting purposes?), but they don't show up under import graphics because it's not in the maps directory. This could be a problem for some graphics like the blood sequence, because it's often used as a static graphic in modding. So obviously, that wouldn't need a script and in some cases it would need to be in a layer other than entity. So how would I place it like so?

I would probably just leave them in the script dir (to keep it flexible) and if you needed it as a static image just have another copy in the map dir. The way to properly take advantage of today's hardware would be to make a 1024X1024 texture and cut and paste all the little static images onto it, this would use less memory.

(2) Another question pertaining to graphics. I've implemented the golden heart from Dink using the coin from Topdown RPG as a template. I was able to make it animate, but it looks weird because it's meant to play through and then reverse. How can this be accomplished in Novashell?

To "bounce" an animation back and forth, enable pingpong in its .xml file.

Example from beerInvader's can.xml:
<animation on_finish="last_frame" pingpong="yes" loop="yes" speed="60"/>


(3) I seem to have a problem grasping how variables work in NS. I need some explanation


Did you do the tutorials? What part is confusing?


(4) Identification of the player. Say I want the player to say 'hello there'. Obviously I would do it like this GetTextManager:Add("hello there.", ent); if it was run from OnAction(ent) or use this if it was run from the player's script itself. But if those aren't available, I need some other way of IDing him. How does that work?

You can get an Ent from a "name". A named entity is inserted into a very fast database and lets you convert a name to an entity whenever you need it.

In most of the examples, the player is named "Player".

Just do:

local ent = GetEntityByName("Player");
if (ent == nil) then
LogMsg("Player ain't found, dumbass!");
end

//ent is now the player, use it for whatever

Some functions want an ID, and not a entity pointer. For those cases, remember that you can do ent:GetID().

Example:

GetCamera:SetEntityTrackingByID(playerEnt:GetID()) ;


(5) A little camera trouble.. So I figured out by research I can make the camera halt by using GetCamera:SetEntityTrackingByID(C_ENTITY_NONE);. That works, but about setting it back.. I can't figure that one out.

See above.


(6) Lastly, I have a problem with said heart's script which I do find odd seeing how I copied most of the code from the coin (again). He just seems to walk right through it without the oncollision function happening. It may be worth noting that I'm using the scripts from the Dink demo as well. Oh and I set the player's category so he'd walk through it.

If you did the tutorials, check out egg.lua, it's a good example. From looking at your code, it looks like you never set it to 'listen' to collisions. (you have to explicitly tell it or OnCollision won't be called)

Add this to your OnPostInit:


//register to get OnCollision calls when the player walks though us.
this:SetCollisionListenCategory(C_CATEGORY_PLAYER, true);


-Pushing:
The big one that scares me. And kind of a necessity for Dink. Would work the same as in dink or zelda.. if the player is against the wall or whatever, he'll play a push animation and that would call some push function on the affected sprite. I'm not even sure how that would work.

Hmm. You'd probably want to have a callback to your OnCollision in your player entity that checks to see if it's a "pushable" object. If it is, you freeze the player control and orchestrate the player's push anim, movement, and the movement of the object he's pushing, based on his direction. Maybe only start it if the player pushes for more than 1 sec or such.

The above would be if you wanted it to look like the original Dink method.

Or, just turn on physics for the object and lot the player literally push it out of the way.


-Camera boundaries:
When the player gets towards the edge of the map, the camera should stop following the player at a certain point. I hope that's clear. It's like when he gets to the edge of a cliff, instead of the camer showing all the way down, it will stop before then and the player will move away from the center of the screen.

There is a function to do this, it's use in the "LowRes" example:

GetCamera:SetLimitToMapArea(true); //try not to show blank parts of the map

Good luck!

rabidwolf9
08-09-2010, 05:00 PM
First of all, thanks so much for the help. I've always been amazed at the games you've mde and how you're like a one man support team answering emails and helping on the forums.

Some more problems/questions if you have the time.

(1)
I seem to be getting this glitchy behavior when overlapping entities. The intersected graphics seem as if they are fighting each other to be displayed on top. It doesn't happen when I'm standing still I don't think, but it happens when I'm moving or punching.

(2)
Clipping: I know you can drag/copy a portion of a graphic and make a smaller one, but is there some kind of clipping with more control like in Dink where you held down a key and you could clip off one pixel at a time?

(3)
Depth que: Putting something on top of something else even when it's higher up on the y axis - How does this work in NS?

(4)
I guess this is similar to the depth que. It seems that with bigger sprites like houses, getting the player to walk behind them at the right point (especially with the diagonal Dink graphics) is a challenge. I've followed the example and clipped the roof and making the base of the house a detail, but there are more bigger angled graphics (like the seige weapons) so how would I go about making them look right when the player is in front of/behind?

(5) [big edit]
More camera trouble. I used GetCamera:SetLimitToMapArea(true); as you said, but when I warp inside a house (it's really small) the map is situated in the corner of the screen. I tried to fix this by using an entity inside the house that covers everything to set it to false and to relocate the screen to the center of the map. I've tried both in the OnInit, OnPostInit, OnMapInsert (I think that's right I'm going from memory here) and finally OnTriggerEnter. The only one that works is the latter, and then it noticably shifts the screen were it belongs. I did some poking around and came across SetMoveLerp and set that to one. There's a noticable difference, but you can still see the screen flash over..

Oh and on the subject of warping, is there some way to do a fade in/out of the screen? Instantly jumping from one map to another is kinda weird.

As for the variables, I completely overlooked the sticky in the tutorials section. That pretty much covers it all. I'll start practicing them when I put in a few of the NPCs.


The way to properly take advantage of today's hardware would be to make a 1024X1024 texture and cut and paste all the little static images onto it, this would use less memory

Darn, I already put them all in single frame and recreated stonebrook pretty much down to every detail. Not to mention ticking the transparency of each of them.. Is it really that big of a deal :p

Added:
I finally got to work with an NPC. After much looking around and gathering samples, I've recreated Dink's mother's initial chats. It uses a choice command and some conversation. So I found out that giving the player a goal will freeze him, but even after all the conversation is done, he still remains frozen. How to I put an end to the goal so he'll move again? I've tried using GetGoalManager():RemoveAllSubgoals(); at the end of the conversation, but that seems to remove the goal right away and let's the player move. I looked at troll attack and didn't see anything that sets the player free of the command and now I'm stumped. Here's the section of script if it helps:



function OnResponse(text, key, dialog) //dialog is passed as a SpecialEntity

//Give player a goal to freeze him
GetPlayer:GetGoalManager():PushNewGoal("Conversation");

if (key == "pig") then
local goal = this:GetGoalManager():PushNewGoal("Talk");
goal:AddSayByID("Mother, how do I feed the pigs I forgot!", g_playerID, this:GetID());
goal:AddSay("That's very amusing, Dink. You get the sack of feed, and you", g_playerID);
goal:AddSay("Sprinkle it in the pig pen. And don't tease them!", g_playerID);
end

if (key == "father") then
local goal = this:GetGoalManager():PushNewGoal("Talk");
goal:AddSayByID("What kind of a man was father?", g_playerID, this:GetID());
goal:AddSay("He was a peasant like us.", g_playerID);
goal:AddSayByID("Was he good with the sword?", g_playerID, this:GetID());
goal:AddSay("Of course not. He was a wonderful farmer and husband.", g_playerID);
end

if (key == "village") then
local goal = this:GetGoalManager():PushNewGoal("Talk");
goal:AddSayByID("Tell me about this village.", g_playerID, this:GetID());
goal:AddSay("The villagers are very friendly. Oh, Ethel wants to see you.", g_playerID);
goal:AddSayByID("Ethel? She's old isn't she?", g_playerID, this:GetID());
goal:AddSay("Yes Dink she is. <Laugh>", g_playerID);
end

if (key == "angry") then
local goal = this:GetGoalManager():PushNewGoal("Talk");
goal:AddSayByID("I hate you!", g_playerID, this:GetID());
goal:AddSay("You'll get over it.", g_playerID);
end

this:GetGoalManager():AddRunScriptString("WonderAround();");
end

Seth
08-11-2010, 02:58 AM
I seem to be getting this glitchy behavior when overlapping entities. The intersected graphics seem as if they are fighting each other to be displayed on top. It doesn't happen when I'm standing still I don't think, but it happens when I'm moving or punching.

Hm - is this happening specifically with the 'checkboard shadows' that Dink uses? That same problem is in that Dink example I did. I suspect it has to do with it freaking out when trying to scroll the screen in sub-pixel increments. A fix would be to convert the shadows to solid, and give them alpha. Or remove them, and let NS draw its own shadows.

If this is not related to the shadows than I'd need more info - perhaps Depth sorting isn't enabled in that layer's properties?


Clipping: I know you can drag/copy a portion of a graphic and make a smaller one, but is there some kind of clipping with more control like in Dink where you held down a key and you could clip off one pixel at a time?

Hmm, no I don't think so. While dragging out a clip box you can do the following though: Zoom in/out, move around with middle mouse button, move the top left of the box instead of the bottom right by holding down Alt. (similar to Photoshop)


(3)
Depth que: Putting something on top of something else even when it's higher up on the y axis - How does this work in NS?

In Dink, you could set the "depth dot" of an item - in NS, it automatically finds it by looking at the bottom of the image, OR the bottom of the collision information.

You can fake it out by making the collision higher or lower than it really needs to be. Look at the candles on the table in the RPG example, I did this for them. (I used the collision type "dummy" so they don't really have collision)

This is a pretty sucky solution though - if you change the collision on one object, they will all change, unless given their own collision data.

A better solution would probably be to add some kind of "attach to image" support. But it can be done with the above hackery.


(4)
I guess this is similar to the depth queue. It seems that with bigger sprites like houses, getting the player to walk behind them at the right point (especially with the diagonal Dink graphics) is a challenge. I've followed the example and clipped the roof and making the base of the house a detail, but there are more bigger angled graphics (like the siege weapons) so how would I go about making them look right when the player is in front of/behind?

Yeah, this is a problem - I believe Dink has the same limitations though (in Dink, we also cut houses in two, right?) so anything possible there should be possible here. Both engines are just not built for diagonal things. A possible solution would be to cut the siege weapon into vertical strips. so the depth queuing would work better.



(5) [big edit]
More camera trouble. I used GetCamera:SetLimitToMapArea(true); as you said, but when I warp inside a house (it's really small) the map is situated in the corner of the screen. I tried to fix this by using an entity inside the house that covers everything to set it to false and to relocate the screen to the center of the map. I've tried both in the OnInit, OnPostInit, OnMapInsert (I think that's right I'm going from memory here) and finally OnTriggerEnter. The only one that works is the latter, and then it noticably shifts the screen were it belongs. I did some poking around and came across SetMoveLerp and set that to one. There's a noticeable difference, but you can still see the screen flash over..


Hmm, sorry, not sure about this one. I've only used SetLimitToMapArea() with the Retro game example.. it may have some issues that need to be worked out. You could disable it when going into houses maybe if that would help.


Oh and on the subject of warping, is there some way to do a fade in/out of the screen? Instantly jumping from one map to another is kinda weird.

The warps are scripts, so it would be possible to freeze the player, fade down, move to the new map, fade back up, unfreeze the player I think. (fades could be handled by drawing a giant black rect over the screen at a layer over the game, but under the GUI and fading it in/out)


Darn, I already put them all in single frame and recreated stonebrook pretty much down to every detail. Not to mention ticking the transparency of each of them.. Is it really that big of a deal

Nah, it's ok. It's just best to keep in mind that internally, most images will be enlarged to be power of 2. So if it's 513X513, it will be 1024X1024 in memory. Dink's images are all over the place so a little will be wasted.


How to I put an end to the goal so he'll move again?

Ok - you push the goal "Conversation" on the player but you will need to remove it manually, as it won't automatically complete because it's empty. (Actually, it seems like it would complete.. you might need to add goal:AddDelay(C_TIME_FOREVER); to stop it from completing)


At the end of your NPC's talking, add this:
goal:AddRunScriptString("GetPlayer:GetGoalManager():GetGoalByName('Conversa tion'):Kill();");

Now the player's dummy goal will be removed when the goal gets to that part.