# Inmate2993

Member

1085

222 Neutral

• Rank
Contributor
1. ## Miss Dodge Hit Calculation Problem

An alternative idea might be to use that Hit% and Evade% as a damage reduction factor. Since HP is regarded as an abstract meter, with every Hit Point representing an ability to deflect a blow from being fatal (with the last HP being the end of that ability). What this means is that every attack would be considered a guaranteed hit, but using Hit and Evade values to determine where the floor parameter of the randomize-damage function lies. (The Offense-Defense values determining the ceiling). My version of this calculation would be something like this. DamagePotential = AttackerOffense - VictimDefense DodgeRate = VictimEvade / AttackerHit DamageActual = Random( DamagePotential * DodgeRate, DamagePotential ) In practice, this formula would probably need a lot of tweaking.
2. ## Turn Based Strategy Movement

Under the A* Pathfinding, assigning different G values to the terrain, and keeping the H heuristic admissible, will find the perfect route every time. There's a couple of things to note about using transports: At the node where a transport can be invoked, each subsequent child node added to the open list should check if it was in the transport at the parent node, to alter the G values. Because they would have a better G value, these nodes have to displace any existing nodes for the location on the open list. This means you can't use a priority queue, and may have to find a better alternative, such as a hashmap.
3. ## Control Scheme for Space Flight

Since it's a game and not a flight simulator, I would say have the LEFT and RIGHT arrows act as a combined yaw and roll control. I believe this was how the starfox games worked. Your area of uniqueness, since it's full 3d, and not 3d on a plane, would be that the spaceship doesn't have to automatically return to that plane, but rather the camera rolls to match the spaceship's plane.

The problem with quick-saving isn't the act of saving at all, it's the act of loading. I could save every turn on an TBS if I wanted to, it wouldn't affect the outcome of a single thing. It's when I reload one of those saved games to redo a particular thing that produces this perceived problem. Some suggest the delete-on-load to fix this. I'm not a big fan of this, given the loss of the crash-protection aspect of saved data. My personal advice would be to fix the part of the gameplay that could be exploited by reloading. If there's a 1 in 10 chance of the enemy automatically killing the player's unit, and the player saves before the fight to remove that possibility, then you have a faulty gameplay mechanic there. The better solution might be to randomize each unit's private unique ID on their creation, and have that 1 in 10 chance of kill be tied to the unique IDs conflicting somehow. That way, a given unit might always face losing against that specific enemy, regardless of the quicksaving.
5. ## Very quick question. (Sorting)

If you pass on the std::list solution, I would recommend a Merge sort, as it's fairly easy to implement. One note to make, however, is that you'll probably have to sap up some memory for the arrays needed for Merge, and the two additional O(n) operations copying the list to an array, and then creating a list from the sorted array.
6. ## Status Changes for my Action/RPG (Revised)

I would suggest having the degradation of the status effects be gradual, and that their initial stats be interleaved, so that typically, only one or two would ever become a problem at any given time. For instance, say at the start of the game, rather than every bar resting at 100%, all waiting to drop to noticeable levels at the same time, start hunger at 75%, so that it would be the first issue the player would need to deal with, and without interruption from others.
7. ## 2D Side-View Pathfinding

A* would still work, except now it's your G values and children nodes that have to be accurately computed. Each node should know its parent node so you'd have to calculate how far it has moved in, say, a jump, making the G value of moving from in a pit to on the floor above it being the maximum integer (since that would be impossible), or not even appear on the children node list.
8. ## A* on a multiple tier map question

The children node of a layer-switching node (a staircase) would include the higher layers, so there's no real problem there. Your heuristic would probably still be a normal distance formula, only with the Z direction appropriately scaled. If your Z size between layers is the same size of the X or Y, then this isn't an issue.
9. ## A*, so close to getting it working.

Do you have a "tie-breaker" to resolve the issue with multiple successor nodes all having the same F values? For the sake of argument, I'll guess no. G is indisputable, as it's the actual cost value, and shouldn't be tampered with. However, H, the Heuristic, is a guess value, and should be carefully tweaked to represent, as close as possible, the cost of the remainder of the trip from the current node. However, with heuristic distances like Manhattan and Euclidean, a lot of nodes will be have the same F distance from the target node (after combining H and G) and will all be considered, wasting time and deprioritizing your open list. The solution, which you should play with, is to add a Tie Breaker to the H value, so that the resulting F values won't all be equal. The easist tie-breaker, is to multiply H by 1.001. The larger the H distance, the less nodes will be considered at the start of the pathfinding. However, this might not fix the zigzagging. Another solution would be to figure out the Cross product of the deal, and use that to form a line between the start and end, which it'll try to follow as best as possible.
10. ## Annoying In-Game GUI?

The best UIs in my experience are the ones that integrate themselves well. It's no coincidence, for example, that the corners of the screen are where more things appear. Those spots out of the way, because vision is circular. However, the center of the screen could be a good place for things that are very immediate and neccessary. Crosshairs. A UI becomes intrusive when it shows you things that you don't need to know. A distance to something when I'm not facing it would be something that's intrusive.
11. ## SDL Fullscreen

SDL may have given you a shadow surface. Use SDL_GetVideoInfo and SDL_ListModes before hand to make sure you are getting the actual surface you want.

This is maybe more of a question for the SDL mailing list. I would think you're encountering a problem of the operating system. Granted, USB is designed for plug-and-play, but the PC joystick protocol was designed in the days of RS232 Serial Ports, when things had to generally be plugged in before powering on the machine. Removing the mouse or keyboard during play would be just as indeterminate. I would suggest not worrying about it. If your game has a need for multiple joysticks during play, specify in the README or Instruction Manual that they should all be plugged in before starting the game.
13. ## SDL and Modplug sound artifacts

My sound engine is a software mixer for a number of running modplug modules, pushed through SDL. I ran into a clicking sounds that I can't seem to get rid of. Changing the buffer lengths changes the tempo of the click, so it's not a buffer underrun. The libraries are up to date (libmodplug 0.8.4 and SDL 1.2.12). And for some reason, the first active module channel is the one that experiences the clicks (so changing the playing module on that channel will still show clicks) I even tried switching it so sound effects play on that channel and the sound effects end up with the clicking. Any ideas? Here's the code. void inm_audio_handler( void *p_udata, Uint8 *p_stream, int p_len ) { int i, j, e; signed int clip; int mods, samps; void * modbuffs[INM_MAX_SOUNDS]; ModPlugFile * module; int bytes = g_inmgame->mixer.bytes_per_sample; int chans = g_inmgame->mixer.sdl_audio_spec->channels; int silence = g_inmgame->mixer.sdl_audio_spec->silence; if (!inm_audio_active) return; /* Clear list of samples playing. */ for ( i=0; i<INM_MAX_SOUNDS; i++ ) modbuffs = 0; /* Generate MOD buffer content. */ mods = 0; switch (bytes) { case 1: for ( i=0; i<INM_MAX_SOUNDS; i++ ) { Sint8 * modbuff = (Sint8 *) g_inmgame->sound.buffer; module = (ModPlugFile *) g_inmgame->sound.module; if ( ( g_inmgame->sound.paused==0 ) && ( modbuff ) && ( module ) ) { modbuffs[mods] = (void *) modbuff; e = ModPlug_Read( module, modbuff, p_len ); if ( e < p_len ) { if ( g_inmgame->sound.looped ) { ModPlug_Loopback( module ); e += ModPlug_Read( module, modbuff+e, p_len-e ); } if ( e < p_len ) { g_inmgame->sound.paused = 1; memset( modbuff+e, 0, p_len-e ); } } mods += 1; } } break; case 2: for ( i=0; i<INM_MAX_SOUNDS; i++ ) { Sint16 * modbuff = (Sint16 *) g_inmgame->sound.buffer; module = (ModPlugFile *) g_inmgame->sound.module; if ( ( g_inmgame->sound.paused==0 ) && ( modbuff ) && ( module ) ) { modbuffs[mods] = (void *) modbuff; e = ModPlug_Read( module, modbuff, p_len ); if ( e < p_len ) { if ( g_inmgame->sound.looped ) { ModPlug_Loopback( module ); e += ModPlug_Read( module, modbuff+e, p_len-e ); } if ( e < p_len ) { g_inmgame->sound.paused = 1; memset( modbuff+e, 0, p_len-e ); } } mods += 1; } } break; } if ( chans > 0 ) { switch (bytes) { case 1: { Sint8 * dst8buff; /* Mix samples into Stream */ dst8buff = (Sint8 *) p_stream; samps = p_len; for ( i=0; i<samps; i++ ) { clip = silence; for ( j=0; j<mods; j++ ) { clip += *(((Sint8 *)modbuffs[j])+i); } /* Perform clipping */ if (clip < S8CMIN) *dst8buff = S8CMIN; else if (clip > S8CMAX) *dst8buff = S8CMAX; else *dst8buff = clip; dst8buff++; } } break; case 2: { Sint16 * dst16buff; /* Mix samples into Stream */ dst16buff = (Sint16 *) p_stream; samps = p_len / 2; for ( i=0; i<samps; i++ ) { clip = silence; for ( j=0; j<mods; j++ ) { clip += *(((Sint16 *)modbuffs[j])+i); } /* Perform clipping */ if (clip < S16CMIN) *dst16buff = S16CMIN; else if (clip > S16CMAX) *dst16buff = S16CMAX; else *dst16buff = clip; dst16buff++; } } break; } } else { /* Clear stream when no samples playing. */ memset( p_stream, 0, p_len ); } }
14. ## predicting algorithm

Quote:Original post by kavelot the problem I find is that the event aren't exactly the same for example, person A may come from work everyday around 6:30pm and turn the lights on, but some days he may come 6:35pm, other days 6:21pm, etc. I could try to use some stats to determine something like "I want a time interval where I'll be correct 90% of the times", but an algorithm like that won't make more complex rules (for example, "it just turn the lights on if there isn't a person on the sector for more than 8 minutes") What you're describing is the need for a Fuzzy Logic system. With a 6:15 to 6:45 fuzzy triangle, 6:35 would be a 0.666~ truth value. That number can be used as part of the calculations for determining events. For instance, with the 6:30AM Event having a higher fuzzier value than the 6:00AM or the 7:00AM events, the 6:30AM event could be the one picked as a reasonable event to base triggers off of. So, if the lights should turn off about 12 hours after being turned on, but aligned to a half-hour mark, the 6:30PM mark would be the target. Like-wise, having a 9:14AM event would push the 9:00PM trigger.
15. ## predicting algorithm

To have events occur based on a history of events, there's no real AI neccessary, just good record keeping. For instance, if an event has happened (and you have a way of knowing the event occured) then you would keep track of it via some means (variables and saved data). To know if a list of events have happened, you check the data to for each event. To produce an AI that reacts based on prior actions the AI itself has made, then you would look into Markov chains. Your history of events can then be kept as an array (or queue) and each entry in the Markov dictionary would be indexed via a subset of the past history. Each dictionary entry contains the list of actions to be performed (and maybe with with a chance of each happening).