Quick Programming Q & A

For discussion of the code running behind the game

Moderator: Staff

Atypikal_Arkitect
Junior Member
Posts: 28
Joined: Tue Aug 11, 2015 1:57 pm

Quick Programming Q & A

Postby Atypikal_Arkitect » Tue Aug 18, 2015 8:13 am

Having a :huh: moment. Post your programming questions here!

I'll start off:

In map_events are a number of defined events dialogue, battle etc. That I imagine through map_bindings are translated and used in the lua files. I was wondering where and how dynamic events are processed, and how would you go about detecting that a mode transition is/will occur(ring) in your current mode?

Thanks
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Tue Aug 18, 2015 2:14 pm

Every map event has a start function and an update function. The start function is called only once when the event begins, and the update function is called continuously until it returns a true value signifying that the event has ended. Dynamic events are done via the CustomEvent and CustomSpriteEvent classes defined in map_events.h. When you construct events of this type, you pass in the name of the Lua function (as opposed to directly implementing the start and update functions in C++). This tells the event what functions it should call when processing the event. It is possible to have no start or no update function for custom events, but you must have one or the other. Take a look at lua/scripts/maps/a01_unblock_underground_river.lua and search for "CustomEvent". You'll see a lot of them defined there.


Detecting a mode transition is a little tricky. You basically have to look for every call to "ModeManager->Push" or "ModeManager->Pop" or "ModeManager->PopAll". These calls are what transition the game from one mode to another. If you're trying to do a transition effect when the mode changes, I recommend adding a transition state to whatever mode you are working in (MapMode and BattleMode both maintain a state variable) and adding a method called "TransitionMode" or something that accepts a game mode that has been created and needs to be pushed, or accepts a pop or pop all operation. Then find all the ModeManager calls in the current game mode and instead of directly pushing the constructed game mode to the mode manager, push the GameMode* pointer to a member of MapMode and call the TransitionMode() function. This will put the mode in the transition state, and you can do whatever else you need to process the transition (graphics, sound, etc) and once the transition effect/processing is done, you can make the appropriate ModeManager call.


Did that all make sense?
Image
Atypikal_Arkitect
Junior Member
Posts: 28
Joined: Tue Aug 11, 2015 1:57 pm

Re: Quick Programming Q & A

Postby Atypikal_Arkitect » Tue Aug 18, 2015 10:00 pm

Yep that makes sense :)

I've had a go at implementing what you mentioned, and in attempt to find why it wasn't working I attempted to debug it. You mentioned that start runs only once when the event begins, my implementation starts from there.

Thing is the BattleEvent create, and the constructor were triggered a few times when the map started up but on actually entering a battle the start method wasn't triggered (it didn't hit the break point I placed there)? (This was on test-mode on the underground cave level)
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Wed Aug 19, 2015 1:23 am

That sounds really strange to me. If Start methods weren't being called sometimes, nothing on maps would work. And if they were called multiple times, things would be broken. I'm looking at the BattleEncounterEvent _Start and _Update methods right now. What you can do is have the _Start change the map state to TRANSITION, let the map do whatever transition effect it needs to, and then have the _Update function check for when the transition is over. If the transition ends, construct the BattleMode object at that point (it is currently being constructed in _Start, so just move that logic over) and then return true. Pushing the mode will start the battle, and returning true will terminate the BattleEncounterEvent on the map. That should work. If it doesn't, you can push your changes to your repository and I can take a closer look at them for you.
Image
Atypikal_Arkitect
Junior Member
Posts: 28
Joined: Tue Aug 11, 2015 1:57 pm

Re: Quick Programming Q & A

Postby Atypikal_Arkitect » Wed Aug 26, 2015 8:52 am

Hey,

I was wondering if I've added a binding to mode_bindings.cpp, how can I test it? In particular for modes that to my understanding are created on the fly like BattleModes.

Thanks,
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Wed Aug 26, 2015 4:01 pm

Usually the best way to test binding code is to use the test interface, if possible. For example, if you're wanting to test a setting change for BattleMode that you bound to Lua, go to lua/test/battles.lua (I think that's the file) and add your binding call to one of the tests there.

Other times when you need to test something that occurs during a map or battle, you can't really modify the test interface because the binding call needs to happen sometime after the map or battle has been loaded. In that case, it's best to modify a map or battle script directly, add the binding call in to it somewhere, and then play through the map or battle and get to the spot where the binding call is made.
Image
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Sun Sep 13, 2015 8:02 pm

Question from another thread:
Djinn_in_Tonic wrote:Just a few questions.

--Where can I find CalculatePhysicalDamageAdder, CalculateStandardEvasionAdder, and so forth? I'd really like to see how those functions work, since we don't have a nice way to, say, code base damage or base evasion for a move in a really easily readable manner (which is a little odd).

--Actually, skip the rest of the questions. The MAIN question is if we have a resource for showing the usage of all our key functions for battle skill development. That would REALLY help.


src/modes/battle_utils.h/.cpp are the files where these are declared and defined.
- battle_utils.h
- battle_utils.cpp

These can of course be modified if we need them to, or moved into Lua entirely if necessary (although we don't have a good place to put them at the moment). The reason they are in C++ is that we don't expect these "base" formulas to need to change much at all. Individual skills may use these formulas and tweak them slightly to make the final damage/evasion formula used a little different.


All of the Calculate...* functions in battle_utils.h I believe are all the key functions for skill development. The attack points (arms, legs, etc) for actors may have a status effect defined that says "if this part is hit, there's this % chance that this status effect will activate). Anything else that a skill does (status effects) are applied directly in the Lua function that implements the skill itself. Note that the CalculateStandard* functions do not need to be used at all. The skill function could do anything it wants to as far changing the values of HP/SP, status effects, etc.
Image
Djinn_in_Tonic
Member
Posts: 67
Joined: Sun Aug 09, 2015 10:36 pm

Re: Quick Programming Q & A

Postby Djinn_in_Tonic » Mon Sep 21, 2015 6:48 pm

Roots wrote:All of the Calculate...* functions in battle_utils.h I believe are all the key functions for skill development. The attack points (arms, legs, etc) for actors may have a status effect defined that says "if this part is hit, there's this % chance that this status effect will activate). Anything else that a skill does (status effects) are applied directly in the Lua function that implements the skill itself. Note that the CalculateStandard* functions do not need to be used at all. The skill function could do anything it wants to as far changing the values of HP/SP, status effects, etc.


Cool. One more quick question...

I'm not entirely familiar with the Gaussian standard deviation function used, and the code doesn't explain the use line-by-line.

Given, say, an average attack - to - defense ratio, how much damage would an expected, say, 0.5 standard deviation value give? What about a 20? Trying to make sure I can target my numbers correctly for anything I want using that.
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Tue Sep 22, 2015 6:43 am

The gaussian distribution code is one of the oldest pieces of code we have. It works just like the mathematical model. Here's a wikipedia page. Look at the graph on the right especially.

https://en.wikipedia.org/wiki/68%E2%80% ... 399.7_rule

So let's say we do our calculations and it's determined that an attack does 40 damage. To apply some variance into this (so we don't deal exactly 40 damage every time), we decide to use a standard deviation of 10% of the base value (40 * 10% = 4). That means that 68% of the time, the damage actually applied will be between 36 and 44. 95% of the time the damage will be between 32 and 48. And nearly 100% of the time, the damage will fall between 28 and 52.

For a given skill, we could apply any standard deviation amount that we want. If we want an attack that is very consistent with the damage dealt, we could make the standard deviation only 2% of the base. On the other hand if we want a "wild swing" skill that can deal great damage or be largely ineffective, we would give it a large standard deviation, maybe 40% of the base.

Does that all make sense? I'm open to applying other variance/distribution models to damage calculation as well. Gaussian was chosen at the time simply because it is well understood and has a decently good distribution spread.
Image
Djinn_in_Tonic
Member
Posts: 67
Joined: Sun Aug 09, 2015 10:36 pm

Re: Quick Programming Q & A

Postby Djinn_in_Tonic » Tue Sep 22, 2015 4:52 pm

Roots wrote:Does that all make sense? I'm open to applying other variance/distribution models to damage calculation as well. Gaussian was chosen at the time simply because it is well understood and has a decently good distribution spread.


Yep.

So, to confirm:

CalculateStandardEvasionAdder takes 2 arguments: the target, and the amount of evasion added (maybe equal to the base % chance of the move to miss).

CalculatePhysicalDamageAdder takes 3 arguments: user, target, and...the last argument passed is the damage boost for that specific move, correct? If so, will the code accept a FOURTH value for the gaussian distribution variance I want? The function does seem to support 4 variables, which is where most of my confusion is coming from, since the maneuver code itself is only passing something like (user, target, 20) instead of what I'd expect as say (user, target, 20, 40) for 20 bonus damage on top of a variance of 40%.

Sorry for all of this clarification, but I'm a *little* rusty on my code (been doing mostly game design and web page work lately), and haven't due into an existing code database in some time. Should be find once I make sure I have this right. *embarassed*
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Tue Sep 22, 2015 5:42 pm

CalculatePhysicalDamageAdder takes 3 arguments: user, target, and...the last argument passed is the damage boost for that specific move, correct? If so, will the code accept a FOURTH value for the gaussian distribution variance I want? The function does seem to support 4 variables, which is where most of my confusion is coming from, since the maneuver code itself is only passing something like (user, target, 20) instead of what I'd expect as say (user, target, 20, 40) for 20 bonus damage on top of a variance of 40%.


  • The third value is the "adder" value that is added or subtracted to the damage, yes
  • There is a version of this function that takes a fourth argument for setting the standard deviation. If you only supply three arguments, it will only use the 3 argument version of the function, which I believe uses the default standard deviation of 10% of the mean.
  • Your (user, target, 20, 40) example is not entirely correct. The fourth argument is a percentage value, not an integer. If you want the standard deviation to be 40%, the value you should pass in for the fourth argument should be "0.4"


Let me briefly explain the different physical damage function naming scheme. There is a "base" function called "CalculatePhysicalDamage". What this does is look at the properties of the attacker and the target and uses the base damage formula to figure out how much damage is dealt. The equation used I believe is something very simple like this: damage = "attacker's strength + attacker's weapon's physical attack - target's fortitude - target's armor's phyiscal defense". If there are no weapons or armor on the attacker/target, then it just becomes "damage = strength - fortitude". If the result is 0 or negative, then instead the function returns a small random number (between 1 and 5 I believe).

Now what the "Adder" functions do is to take the result of the base formula and add some integer value (could be either positive or negative). If we want a particular skill to add a bonus 40 damage to the standard physical attack, we'd use the adder function to do so. The "Multiplier" function, on the other hand, takes the result returned by the base formula and multiplies it by a number you give it. So if you want to create a skill that only deals 60% of the damage of the standard formula, you'd pass in "0.6" to the multipler function. Some of these functions accept an additional standard deviation argument, which affects the amount of variance in the value that can be returned by the function (the "mean" value will always be the same).

However, just because these formulas exist does not mean you are forced to use them. You have the freedom to create custom damage formulas for any skill. For example, one that always reduces the enemy's HP by 10%. You get passed in the user and target of a skill, so if you wanted to you could pull in all of their various stats, equipment, any active status effects, and so on and create some completely custom formula based on that data. The functions we use now are just "common formulas" that we want to make easy to re-use. If you want to know how to make a custom formula, just ask me. Or better yet, you might just tell me what you want the formula to be, I can code it up real quick, and then you can look and see how it was done to help you figure out how to write custom formulas.


Also, I know these formulas are really basic, as it doesn't get much simpler than damage = physical attack - physical defense. If we want to (or need to) do something more complicated, by all means crunch some numbers and figure out a better system. A long while back I took a look at another RPG's damage formulas (I think it was FFVI and I found the information on gamefaqs.com), and the formulas used there were a lot more complex than I thought they would be. :shrug: I copied the comments for the various physical damage formulas below (there's a corresponding set for ethereal damage). These should answer most concerns I think. These comments are found in src/modes/battle/battle_utils.h

Code: Select all

/** \brief Determines the amount of damage caused with a physical attack
*** \param attacker A pointer to the attacker who is causing the damage
*** \param target A pointer to the target that will be receiving the damage
*** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
***
*** This function uses the physical attack/defense ratings to calculate the total damage caused. This function
*** uses a gaussian random distribution with a standard deviation of ten percent to perform variation in the
*** damage caused. Therefore this function may return different values each time it is called with the same arguments.
*** If the amount of damage calculates out to zero, a small random non-zero value will be returned instead.
**/
uint32 CalculatePhysicalDamage(BattleActor* attacker, BattleTarget* target);

/** \brief Determines the amount of damage caused with a physical attack
*** \param attacker A pointer to the attacker who is causing the damage
*** \param target A pointer to the target that will be receiving the damage
*** \param std_dev The standard deviation to use in the gaussian distribution, where "0.075f" would represent 7.5% standard deviation
*** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
***
*** The std_dev value is always relative to the amount of absolute damage calculated prior to the gaussian randomization.
*** This means that you can -not- use this function to declare an absolute standard deviation, such as a value of 20 damage
*** points.
**/
uint32 CalculatePhysicalDamage(BattleActor* attacker, BattleTarget* target, float std_dev);

/** \brief Determines the amount of damage caused with a physical attack, utilizing an addition modifier
*** \param attacker A pointer to the attacker who is causing the damage
*** \param target A pointer to the target that will be receiving the damage
*** \param add_atk An additional amount to add to the physical damage dealt
*** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
***
*** The add_atk argument may be positive or negative. Large negative values can skew the damage calculation
*** and cause the damage dealt to drop to zero, so be cautious when setting this argument to a negative value.
**/
uint32 CalculatePhysicalDamageAdder(BattleActor* attacker, BattleTarget* target, int32 add_atk);

/** \brief Determines the amount of damage caused with a physical attack, utilizing an addition modifier
*** \param attacker A pointer to the attacker who is causing the damage
*** \param target A pointer to the target that will be receiving the damage
*** \param add_atk An additional amount to add to the physical damage dealt
*** \param std_dev The standard deviation to use in the gaussian distribution, where "0.075f" would represent 7.5% standard deviation
*** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
**/
uint32 CalculatePhysicalDamageAdder(BattleActor* attacker, BattleTarget* target, int32 add_atk, float std_dev);

/** \brief Determines the amount of damage caused with a physical attack, utilizing a mulitplication modifier
*** \param attacker A pointer to the attacker who is causing the damage
*** \param target A pointer to the target that will be receiving the damage
*** \param mul_atk An additional amount to be multiplied to the physical damage dealt
*** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
***
*** This function operates the same as the CalculatePhysicalDamageAdder(...) functions with the exception that
*** its float argument is used as a multipler in the damage calculation instead of an integer addition modifier.
*** So for instance if the user wants the physical damage to decrease by 20% the value of mul_atk would
*** be 0.8f. If a negative multiplier value is passed to this function, its absoute value will be used and
*** a warning will be printed.
**/
uint32 CalculatePhysicalDamageMultiplier(BattleActor* attacker, BattleTarget* target, float mul_phys);

/** \brief Determines the amount of damage caused with a physical attack, utilizing a multiplication modifier
*** \param attacker A pointer to the attacker who is causing the damage
*** \param target A pointer to the target that will be receiving the damage
*** \param mul_atk A modifier to be multiplied to the physical damage dealt
*** \param std_dev The standard deviation to use in the gaussian distribution, where "0.075f" would represent 7.5% standard deviation
*** \return The amount of damage dealt, which will always be a non-zero value unless there was an error
***
*** This function signature allows the additional option of setting the standard deviation in the gaussian random value calculation.
**/
uint32 CalculatePhysicalDamageMultiplier(BattleActor* attacker, BattleTarget* target, float mul_atk, float std_dev);
Image
Djinn_in_Tonic
Member
Posts: 67
Joined: Sun Aug 09, 2015 10:36 pm

Re: Quick Programming Q & A

Postby Djinn_in_Tonic » Tue Sep 22, 2015 5:56 pm

Roots wrote:*Snip*


Thanks a million. That's all super helpful. I might recommend we make sure we comment things a bit more in-depth going forward though, just so we don't have to explain this sort of thing every time. I know *I* tend to be really detailed, at least -- hope that's not an issue.

However, just because these formulas exist does not mean you are forced to use them. You have the freedom to create custom damage formulas for any skill. For example, one that always reduces the enemy's HP by 10%. You get passed in the user and target of a skill, so if you wanted to you could pull in all of their various stats, equipment, any active status effects, and so on and create some completely custom formula based on that data. The functions we use now are just "common formulas" that we want to make easy to re-use. If you want to know how to make a custom formula, just ask me. Or better yet, you might just tell me what you want the formula to be, I can code it up real quick, and then you can look and see how it was done to help you figure out how to write custom formulas.


Oh, absolutely. I just wanted to make sure I knew how the current set-up worked, so I understood what we're CURRENTLY doing.

Also, I know these formulas are really basic, as it doesn't get much simpler than damage = physical attack - physical defense.


That's fine, honestly. But what it does mean is that the difference in a move's strength varies greatly as characters advance in health. Since physical attack and physical defense are probably going to have a roughly equal relationship as the game progresses, that value will probably be more or less constant. But the 20 damage from Basic Slash 1 is going to be a LOT less valuable against 7000 health than it will against 200 health.

So we'll need to look at our progression formulas (and our expected physical attack / defense growth) to determine what change we'll need there. My gut instinct is probably a level growth multiplier of some sort applied to the total damage.
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Wed Sep 23, 2015 12:56 am

Djinn_in_Tonic wrote:Thanks a million. That's all super helpful. I might recommend we make sure we comment things a bit more in-depth going forward though, just so we don't have to explain this sort of thing every time. I know *I* tend to be really detailed, at least -- hope that's not an issue.


Of course. I'm very detailed myself, but there's a ton of code to document and it changes all the time, so it's hard to keep up. I try to encourage/coerce others into documenting what they are working on in the past, but to little effect. Most programmers, sadly, either don't care enough or simply don't want to write documentation. Some parts will always be better documented in others. So just ask questions when you're in doubt about something.

Djinn_in_Tonic wrote:That's fine, honestly. But what it does mean is that the difference in a move's strength varies greatly as characters advance in health. Since physical attack and physical defense are probably going to have a roughly equal relationship as the game progresses, that value will probably be more or less constant. But the 20 damage from Basic Slash 1 is going to be a LOT less valuable against 7000 health than it will against 200 health.

So we'll need to look at our progression formulas (and our expected physical attack / defense growth) to determine what change we'll need there. My gut instinct is probably a level growth multiplier of some sort applied to the total damage.


You make an excellent point there, and this is something that I've been thinking about in the back of my mind. Essentially, I don't want skills to become useless during the course of the game. So I thought why not make skills grow and change throughout the game, or be replaced by clearly superior versions of existing skills? For example, Basic Slash 1 gets replaced by Basic Slash 2 after another 12 levels of experience, and it deals more damage at the same SP cost. Or maybe the player completes a side quest which unlocks a new technique that makes an existing skill even better, reducing the SP cost, and increasing the power. There's really no limit to what we can do here. Although if we're replacing existing skills, we'd want to be sure that we're offering a clearly better choice and that the player won't be "missing" having that old skill around.

Just a thought. Could also make balancing easier since we don't need the abilities of skills to "scale" with the growth of characters and enemies throughout the game.

I had an idea the other day that has me pretty excited.
Image
Atypikal_Arkitect
Junior Member
Posts: 28
Joined: Tue Aug 11, 2015 1:57 pm

Re: Quick Programming Q & A

Postby Atypikal_Arkitect » Tue Oct 13, 2015 7:45 pm

Hey I've just started with some scripting and thought this would make for a good question for project newcomers to scripting.

Do you have any best practice advice/tips regarding scripting in the project, and debugging them?
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Wed Oct 14, 2015 6:32 am

That's a great question. I'm still in the process of figuring out the best answers myself. In fact, I have some changes that I haven't pushed to my repository yet that are directly related to this.

The most painful issue with map script development is that you need to test different events, dialogues, etc. on a map, all of which occur at different locations and perhaps under different conditions (ie, there may be some decision or action the player made earlier in the map that affects something that happens later). In the past, what I've done is temporarily modified the Load() function for the script to put the player's sprite at a certain position and put them in the proper context if there are multiple map contexts. I'd also comment out any event chain that is started by the Load() function (some maps start an event right away to play out a scene). I'd keep the debugging code until I was "done" testing whatever it was nearby that I needed to test, and then discard those temporary changes.


That's pretty inefficient and sloppy, especially because it's often the case that you'll need to go back and re-test that part of the map, and you have to add all that code back in (and you probably don't remember all of the coordinates and conditions you needed to set). What I'm doing with the capital_attack map right now is to add a new variable integer to the file, tentatively called something like (DEBUG_LOAD), and a new function called DEBUG_Load(). Here's what happens:

  • When DEBUG_LOAD is set to 0, the map runs as it normally would and no debugging code is called
  • If you set it to any non-zero value, then at the end of the Load() function where it would normally set sprite coordinates, start events, and do other sorts of conditions, instead it calls the DEBUG_Load() function
  • DEBUG_Load() is a big if/elseif/else statement that sets up different debugging conditions depending on the value of DEBUG_LOAD and then returns. Each conditional statement is prepended with a comment indicating what setting DEBUG_LOAD to that value does (ie: 1 == skip past introductory map scene, 2 == move player to just outside of the throne room, etc).
  • The else case prints a warning to let the developer know they selected an invalid debugging code

I'm not sure if this is the best way (I'd love to hear alternative suggestions), but it's much better than what I was doing before. Also because LOAD_DEBUG has a scope of the entire file and not just a single function, you could add checking for this value in all other functions, like the Create() functions, Update() or Draw() function, etc. Obviously you can't have two debug conditions run at the same time, which is the major downside of this approach.


Other general tips:
  • Test often. Lua scripts don't compile and when a script runs, it usually doesn't give you any helpful debugging information about where the script failed. This is the reason why all the Create() functions make a call to IfPrintDebug(DEBUG, "message") at the top, so it's easier to tell where a script failed during load
  • You don't need to re-start the application for every test of a map. Simply hit Ctrl+T to return to the test interface, select the same map, and it will load it all over again, fresh with whatever recent changes you made to the Lua file (make sure you DO save your edits to the file, obviously).
  • One of the annoying/tedious parts is keeping track of all the various IDs. You have IDs for sprites, dialogues, objects, events, etc. Please don't try to manually use IDs where you don't have to (we did that before, and it was a pain). Instead, maintain a local reference to the object and grab its ID directly. For example: sprites["claudius"]:GetObjectID().
  • Remember that the scripting code runs only once per frame and you shouldn't be doing something like "while (sprite.location != destination) sprite:MoveToLocation(x, y)". That code would re-compute the path for the sprite EVERY frame, and would really slow the game down, especially for multiple sprites moving at a time. The purpose of the event system is to help manage that, so make use of events wherever you can. And create a CustomEvent if you need something unique.
Image
Lordakius
Junior Member
Posts: 26
Joined: Thu May 26, 2016 9:22 pm

Re: Quick Programming Q & A

Postby Lordakius » Sun Sep 18, 2016 3:55 pm

Let's make it short here:
-Any way to stop your code at a specific location ?

Code: Select all

if (variable == true)
   {
       //stop
      do_that;
   }


-in input.h there is this list of functions(?). Where exactly are the buttons defined, which activate them?
(see input.h line 588 to 605)

Code: Select all

   /** \name  Input Press Members
   *** \brief Retain whether an input key/button was just pressed
   [...]
      bool _help_press; //<=this is the one i am looking for
   


-Is there a way to debug code step by step with Code:Blocks? So you can check where your program goes in every flow control statement?

-Okay, so here we define an object 'ev', member class of SDL_Event, which gets the last incoming button/key press. But it doesn't get called here, right? Is there any way to check for calls to that function in the code?

Code: Select all

   // Check for waiting keypresses or joystick button presses
   SDL_Event ev = InputManager->GetMostRecentEvent();


-And, because I have never worked in such a project before: where is the main.cpp (or an accordingly file)? The one, which actually is the start of the program
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Sun Sep 18, 2016 5:02 pm

Lordakius wrote:-Any way to stop your code at a specific location ?


Use a debugger if you want to pause execution of code. There's no code you write that will just stop execution.

Lordakius wrote:-in input.h there is this list of functions(?). Where exactly are the buttons defined, which activate them?


Keys are defined in lua/data/config/settings.lua. But the help_press key is not, because its not a user-configurable one. It is hard-coded to F1 somewhere in the C++ input engine code.

Lordakius wrote:-Is there a way to debug code step by step with Code:Blocks? So you can check where your program goes in every flow control statement?


I'm sure that there is. I've never used it myself because I do almost all of my programming and debugging in Linux (I use kdebug if I need to step through code). Google is probably a better answer here. And I think you might have to use the Windows Debug target (not Windows Release). Otherwise the debugging information doesn't get compiled into the .exe.

Lordakius wrote:-Okay, so here we define an object 'ev', member class of SDL_Event, which gets the last incoming button/key press. But it doesn't get called here, right? Is there any way to check for calls to that function in the code?


Yes, that is a call to GetMostRecentEvent() on that line. In Linux if I want to know where a function gets called, I just run a grep command in the src and/or lua directory: "grep -nr GetMostRecentEvent". Sorry, but I don't know how to do this in Windows.

Are you diving around in the input engine just for learning? The issue that is assigned to you shouldn't require you diving into that code. You just need to focus on the code for boot mode (src/modes/boot).

Lordakius wrote:-And, because I have never worked in such a project before: where is the main.cpp (or an accordingly file)? The one, which actually is the start of the program


src/main.cpp
Image
User avatar
Jormuny
Newbie
Posts: 10
Joined: Mon Aug 22, 2016 8:37 pm

Re: Quick Programming Q & A

Postby Jormuny » Sun Sep 18, 2016 7:37 pm

Lordakius wrote:-Is there a way to debug code step by step with Code:Blocks? So you can check where your program goes in every flow control statement?


Since I stick to C::B (linux or no) I can answer that:
Between the code itself and the line numbers is a small gray space. Left-clicking there creates a breakpoint (a lil' red circle) for that line.

You then start the the program via the debug/continue button rather than run (Under the Debug menu, or F8 on your keyboard). The program should run until it hits the breakpoint, etc, and then you have all the "stepping" options also under the Debug menu, such "Next Line" or "Step Into", etc.

Hope this helps! :)

EDIT: And yeah, you probably need to ensure you're compiling "Debug Win32" rather than the release one
Lordakius
Junior Member
Posts: 26
Joined: Thu May 26, 2016 9:22 pm

Re: Quick Programming Q & A

Postby Lordakius » Mon Sep 19, 2016 10:42 am

Thanks, I'll try that out :)

@Roots: yeah, since I haven't developed any of these lines, I'm pretty confused sometimes what happens there^^ I like to look around and follow the code to learn how it works. Basically I know what to do, but I have some problems with finding the right place to insert.

That's why I want to know how to follow the code. I will try to find the function and if I am not able to, I'll come back and ask for help ^_^

*Edit:

Code: Select all

Continuing...
Program received signal SIGTRAP, Trace/breakpoint trap.
In __cxa_throw () ()
246   ./src/main/win32/SDL_win32_main.c: No such file or directory.
#10 0x00573cfb in console_main (argc=1, argv=0x1143ce0) at ./src/main/win32/SDL_win32_main.c:246


This happened when I wanted to compile with Debug/Continue after creating a breakpoint. Not sure what the problem is exactly. (I have looked through the allacrost local directory and didn't find the scr/main/ folder ... but why should it refers to a file outside of the game directory?)
User avatar
Roots
Dictator
Posts: 8666
Joined: Wed Jun 16, 2004 6:07 pm
Location: Austin TX
Contact:

Re: Quick Programming Q & A

Postby Roots » Mon Sep 19, 2016 3:38 pm

SDL_win32_main.c is not a file that exists in our system. I know virtually nothing about windows debugging, but I can make two guesses as to why this happens. 1) you don't have the libraries setup correctly (but if you can run the game fine in non-debug mode right now, it's probably not this). 2) you need to either use the debugging version of those libraries, or copy over the debugging files that are distributed with SDL (not sure if we do that or not). Make sure you have the latest package and build files, as I recently added a .zip file for all the windows libs into the repository. You can read instructions for how this should work here: http://www.allacrost.org/wiki/index.php ... structions


Jormuny, does the C::B build system on Linux completely ignore all the autotools configure and make files? Or did you configure the build process to use our existing make file structure? Just curious to know since I've never used C::B to build on Linux.
Image

Return to “Programming”

Who is online

Users browsing this forum: No registered users and 2 guests