Golden Sun Hacking Community

Golden Sun Resources => Misc. GS Hacking => Topic started by: charon the ferryman on 29, August, 2016, 09:06:45 AM

Title: How does Golden Sun handle movement?
Post by: charon the ferryman on 29, August, 2016, 09:06:45 AM
I'm not really concerned about collisions, but I'm curious to know more about how Golden Sun handles moving/rotating the sprite and movement. I want to do something similar with my current game Colors but adapt it for what I've already built out. My current game feels so jerky and it basically uses the same angle/rotation so I want to model it off of Golden Sun's engine here.

Does anyone have the code of how this is handled? Or at least a model or explanation on how it works on a logical level? Like if I wanted to port it in Java or something like that. Thanks.
Title: Re: How does Golden Sun handle movement?
Post by: leaf on 29, August, 2016, 02:53:16 PM
If it feels jerky, there's a few possible problems:

1) Lack of acceleration
2) Lack of necessary blend states
3) Poor camera movement

The first is easy to fix. Just give the player an initial speed for tapping the key to move, then accelerate up to their max speed as long as it remains held. The acceleration should take place over a few frames at most. When the key is released, strong friction should kick in and bring them to a stop (again, over several frames). For reversing direction, apply friction *and* the new force, resulting in a faster transition between moving in one direction to the other.

The second is a harder fix, because it's chiefly an art problem. If you already have acceleration built into the character, you may need additional blend states for going between moving and idle, or between different movement directions.

It's a little hard to tell if #3 is relevant based on your description, but if this is the case, you'll just have to fine-tune your camera bounds, smoothing speed, and so on.
Title: Re: How does Golden Sun handle movement?
Post by: Daddy Poi's Oily Gorillas on 29, August, 2016, 03:25:16 PM
Should be easy enough to explain how the code works, maybe... (Will want to look into it again, but I'll paste the relevant documentation here.)

The NPC data in RAM... starts with an address to NPC script code... and for the PC, the data there relates to movement... so the code that refers to that, I shall list:

Quote0802632C = Data Script 23 - Hover
08026362 = Hover running speed
08026368 = Hover initial running speed/end traction
0802636E = Hover running animation
08026374 = Hover walking speed
0802637A = Hover initial walking speed
080267BC = Data Script 24 - Slippery Ground
080267EC = Slippery running speed
080267F4 = Slippery initial running speed (lower traction means that it takes longer to reach full speed)
080267FA = Slippery running animation
08026802 = Slippery walking speed
0802680A = Slippery initial walking speed (lower traction means that it takes longer to reach full speed)
08026DD0 = Sets psynergy to use on map. (At least for shortcuts.)
08026E60 = Related to button controls and menus?
08026F80 = Collision detection? Removing the code makes it so you can't move without holding L in debug mode
08026FC8 = (BL in Data Script 19)?
08027064 = Data Script 19 - Normal movement - Gives you the ability to move your character.
080270A6 = Running speed
080270AE = Initial running speed (starts at this before changing to normal value)
080270B2 = Running animation
080270BA = Walking speed
080270C2 = Initial walking speed (starts at this before changing to normal value)
0802726E = Debug mode: Walk through walls
080276A2 = Pushing NPCs animation (not used in all instances, such as with pushing psynergy obstacles)
080276C2 = Idle animation (not moving)
080276C8 = Idle animation when party leader has 0 HP
080279B0 = Data Script 1A - Overworld movement
080279DE = Running speed
080279E4 = Initial running speed
080279EA = Running animation
080279F0 = Walking speed
080279F6 = Initial walking speed
08027A50 = Debug mode: Walk through walls (There's also a Flag 0x163 check. (Can be used instead of the L button, if necessary.)
08027E0C = Data Script 25 - Calls 08026E60 - No movement. Access to menus/psynergy shortcuts.
08027E20 = Data Script 1F - Overworld thing; walk through everything, objects are solid
08027E38 = Debug mode: L button check that doesn't seem to do anything special?
08027FAA = Debug mode: Walk through walls
08028534 = Data Script 20 - Ship mode
08028608 = Debug mode: L button check
08028AAC = Data Script 21 - Hover Ship mode
08028B96 = Debug mode: L button check
080290F4 = Data Script 1B - Climbing wall
0802910A = Debug mode (Nothing special?)
08029110 = Idle climbing animation (when not moving)
0802914C = Climbing right animation
08029156 = Climbing left animation
0802915E = Climbing up/down animation
0802920E = Hitting wall/dead end animation
08029262 = Animation before climbing up/hitting ground
080292FC = Data Script 1C - Climbing rope
08029570 = Data Script 1D - Walking rope
08029810 = Unused? Loads a value from 02000474
08029838
080298C0 = Data Script 1E - Sand
080299A2 = Debug mode (Nothing special?)
08029C94 = Debug mode: L button check
0802A124 = Data Script 22 - Sand (World Map)
0802A1BC = Debug mode: L button check
Well, not everything about all of them are detailed, but I hope this will help you get an idea. (And assuming you know assembly, then you can see instruction for instruction what is going on.)
Title: Re: How does Golden Sun handle movement?
Post by: Luna_blade on 29, August, 2016, 04:59:48 PM
Your game is in GML right?

Like leaf said. Use speed = speed + accel
and set a high friction.

In GS, AFAIK, the accel is really high and the friction as wel.

Have you looked in diagonal movement yet?
Title: Re: How does Golden Sun handle movement?
Post by: charon the ferryman on 10, September, 2016, 12:51:16 AM
Currently I've got something down that works for now.

What I did was I built a pulley simulator for the rotation, so basically when you press down on a key, it "pulls" on a circle with a "string" in that direction until it orients it that direction. This means basically the further the orientation is from the desired rotation, the more time it needs to accelerate to get to the desired rotation. This takes place on a super small scale though so it's not really noticeable to the player.

Now comes the fun of collisions... welp.
Title: Re: How does Golden Sun handle movement?
Post by: Atrius on 25, September, 2016, 01:01:08 PM
Hello again.

I actually did a lot of work on figuring out exactly how movement worked in Golden Sun.  It's been a while so my memory is pretty fuzzy, but I still have some code lying around I wrote to mimic it for my Flash tech demo (http://forum.goldensunhacking.net/index.php?topic=51.0).



The basic code for movement I did was separated into two functions, one for handling input for the player, and another one that EVERY character in the engine used to handle movement.

The function for the player
Note that keyDirectionHeld would be set to 1 if they corresponding key was held, and 0 if not.


xMove = keyRightHeld - keyLeftHeld;
yMove = keyDownHeld - keyUpHeld;

// Does the player want to move?
if (xMove != 0 || yMove != 0) {
dirMove = direction(0, 0, xMove, yMove); // Calculate direction player wants to move

moving = true;

if (keyRunHeld)
speedMax = 1.5; // Running max speed
else
speedMax = 1; // Walking max speed

if (speed > .25) {
if (keyRunHeld)
animation = 5; // Animation 5 is the running animation
else
animation = 2; // Animation 2 is the walking animation
} else {
animation = 9; // Animation 9 is the idle animation
dirFace = dirMove; // Force facing direction to direction player wants to move;
}
} else {
moving = false;
speed = 0; // Player stops immediately when buttons are released
animation = 9; // Animation 9 is the idle animation
}



This one handles movement of ALL characters


if (moving) {
speed += acceleration;
if (speed > maxSpeed)
speed = maxSpeed;
} else if (speed > 0) {
speed -= acceleration;
if (speed < 0)
speed = 0;
}

if (speed>0) {
xPrevious = x;
yPrevious = y;

// This function moves the actor the distance of "speed" in the direction of "dirMove"
// It also handles collisions, and sliding the character around obstacles
moveDirection(speed, dirMove);

// Face the character the direction they're moving
if (x != xPrevious || y != yPrevious)
dirFace=direction(xPrevious, yPrevious, x, y);  // Calculates direction between 2 points
}


In Golden Sun's engine, "acceleration" is 0.25 for the player.

moveDirection(distance, direction) is where the character's position is actually changed, and collisions are handled.  Here's a post (http://forum.goldensunhacking.net/index.php?topic=2545.msg42753#msg42753) I made a while back that goes into the details of how collisions work in Golden Suns engine.  There's a lot of good info later on in that topic too.


Additionally, the character's sprite facing direction is eased so they turn gradually instead of instantly.

if (dirFace != dirSprite) {
// Normalize dirFace so the sprite turns the quickest way to face correctly
if (dirFace - dirSprite > 180)
dirFace -= 360;
else if (dirFace - dirSprite <= -180)
dirFace += 360;

// Calculate direction change
dirChange = dirFace - dirSprite;
if (dirChange > 22.5)
dirChange = 22.5;
if (dirChange < -22.5)
dirChange = -22.5;

// Add direction change, normalizing output between 0 and 360
dirSprite = (dirSprite + dirChange + 360) % 360; 
}
Title: Re: How does Golden Sun handle movement?
Post by: charon the ferryman on 26, September, 2016, 09:08:28 PM
hoooooooooooooly crap thank you atrius you are freaking awesome