Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
I'm not familiar with how Godot transforms work, so I'm not 100% clear on what your code snippets are actually doing. Having said that:

What the code snippets you found are doing is averaging two points together. The .5 comes in because there's 2 points in question. For example, say one point P1 is (1,2,3) and the other P2 is (5,6,7). The average is (P1+P2)/2, or ((1+5),(2+6),(3+7))/2, or (3,4,5). The reason you can't get what you want by multiplying by .15 is because that's not how averages work.

What you want to do instead is get the vector from one point to another point. You do this by subtracting the start point from the end point. If our start point is P1 and our end point is P2, then the vector is P2-P1, or (5-1,6-2,7-3), or (4,4,4). Call this vector D. What this says is "if you add (4,4,4) to P1, you will get P2". Or equivalently, you can get any fraction of the distance from P1 to P2 by multiplying that vector by the fractional amount. So if you want a point that's 15% of the way from P1 to P2, you'd do P1 + .15*D, or (1,2,3) + .15*(4,4,4), which works out to (1.6,2.6,3.6).

Another thing you can do is normalize D, which means that you divide it by its distance from the origin. This makes its magnitude be 1. In this case, D_norm (normalized D) is (.577,.577,.577). Then you can find a point that is a set distance from P1 towards P2 by just multiplying the normalized vector by the distance you want. For example, if you wanted to find a point that is 2 units away from P1 on the line to P2, you'd do P1+2*D_norm, or (1,2,3) + 2*(.577,.577,.577).

e:f;b

Adbot
ADBOT LOVES YOU

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Notice that the code you've written it's symmetric - if you swapped the character position and the aim point in your code, you'd get the same number back out, so how is it ever going to be weighted towards one of them over the other?

The basic formula for a weighted average is (aX + bY + ...)/(a + b + ...). With two vectors and wanting to find the midpoint (i.e. weight them evenly) this works out to (X+Y)/2, as you might expect. If you want to weight it 85% towards one option, you could do (85X + 15Y)/100.

CH Science
Sep 11, 2019

Awesome, thanks all. Definitely have a better understanding of what I should have been doing (and what the code snippets I found while searching were doing) now. Still gonna dig in and learn some more but at least its acting like it's supposed to now:

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

CH Science posted:

Well that was fast! Thanks for the explaination. Makes sense and works perfectly
Or for more like the way you were trying to do it, you can do it like
code:
fraction = 0.15
fractionalPoint = originPoint * fraction + targetPoint * (1.0-fraction)
And if you wanted a fixed distance along the line rather than a fraction, then you have to do it more like the way Jewel said, but

code:
fractionalPoint = originPoint + fromSelfToTarget.normalized * desiredDistance

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
I'm having an issue with my particle systems' ribbon trails, where they often have jaggies in them that I think are because of twisting of the ribbon.



https://i.imgur.com/aOiSEkD.mp4

I've tried editing every part of the particle system that I can think of, and nothing seems to fix it. Even when the trails are moving along a smooth path with a consistent orientation relative to the camera, they'll just sometimes wig out and create a bunch of jaggies. The particle system is very simple: it emits 1 particle per world unit of distance. The particle grows and changes opacity over time, but has no renderer. There's a ribbon trail (1 ribbon per emitter) that uses the size/color of the parent particle to control its appearance.

Any ideas? Google hasn't been much help.

EDIT:
https://i.imgur.com/NlJsiDw.mp4

Looks like it only happens when the particle system is moving quickly, which makes me wonder if Unity's getting confused about what order the particles are in if I spawn more than 1 in a single frame. Setting emission to 30 per second instead of 1 per unit seems to help, and is a workable solution in this case...but I can't use that solution for all of my trails.

TooMuchAbstraction fucked around with this message at 21:43 on Aug 26, 2021

KillHour
Oct 28, 2007


I'd file it as a bug with unity. You might have to manually edit the object structure to fix whatever gets messed up.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Yeah, I went ahead and did that. We'll see if anything comes of it.

EDIT: and they told me to upgrade to 2020, of course. I'm still on 2019. I guess it's worth at least checking to see if the most recent versions of Unity have actually fixed this.

TooMuchAbstraction fucked around with this message at 21:32 on Aug 28, 2021

Gin_Rummy
Aug 4, 2007
I'm having some trouble getting my basic movement system to work properly in C#/Unity, hopefully someone here might be able to nudge me in the right direction.

I have a cylinder that I want to have roll and turn, so I have my cylinder game object, and scripted an empty coordinate system game object so that the csys's position is always equal to my cylinder's. My idea was that since the x-vector of my actual cylinder would constantly be rotating, I shouldn't apply my velocity to that, so I try and set my csys to always be pointing "forward" and apply the velocity to that. So far, it essentially works... I can turn and rotate my cylinder and the csys follows it, however once I begin to roll, my csys will constantly "flip." So basically I get it cycling as shown between the two images below, when I am trying to just have the first image remain constant. This makes it so that I am consistently having my velocity shift from "forwards" to "backwards."




So I am sure this has something to do with the fact that my csys position is still related to which direction the cylinder's x-vector is pointing on a per frame basis, but I have no idea how to decouple the two and just make my csys's x-vector fixed "towards front."

Gin_Rummy fucked around with this message at 18:35 on Aug 31, 2021

Ruzihm
Aug 11, 2010

Group up and push mid, proletariat!



I don't know if you solved this problem already but assuming cylinder's local x axis always points towards the cylinder's right, you can use a cross product to find its "forward" direction, using the world's up as a basis.

code:
Vector3 fwdDir = Vector3.Cross(transform.right, Vector3.up); 

Ruzihm fucked around with this message at 17:40 on Sep 3, 2021

Gin_Rummy
Aug 4, 2007

Ruzihm posted:

I don't know if you solved this problem already but assuming cylinder's local x axis always points towards the cylinder's right, you can use a cross product to find its "forward" direction, using the world's up as a basis.

code:
Vector3 fwdDir = Vector3.Cross(transform.right, Vector3.up); 

I'm fairly certain I tried something like this already, but it might not have been exactly this. I'll give it a go and report back.

Ruzihm
Aug 11, 2010

Group up and push mid, proletariat!


Gin_Rummy posted:

I'm fairly certain I tried something like this already, but it might not have been exactly this. I'll give it a go and report back.

Good luck, and if you're interested in having the forward be in relation to the surface the cylinder is on, you should be able to use the surface's normal instead of Vector3.up.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Well, now I'm pissed off at Steam. My game launched in the middle of July. Steam sends payments only once a month, on the 30th...and they also don't send any money that they haven't held onto for at least 30 days. Which is kind of scummy but I can see justifications for it (mostly around refunds). So I don't get any payment until August 30th.

In an astounding set of bad timing, my bank, BlueVine, did a big transition that involved changing their routing numbers, also timed for the 30th. I gave Steam the updated account information and hoped for the best...unfortunately they sent their payment early and so of course it failed. No big deal, I contacted them and asked them to try again. Response: no, we only send payments once per month, you'll have to wait another month. I pointed out that I'm a small dev, the launch money represents a significant amount of income for me, and the payment failed due to factors entirely outside of my control. Response: sorry, no, wait a month.

My game's been out for ~50 days now and I haven't seen a single cent from it yet. :mad:

Tann
Apr 1, 2009

TooMuchAbstraction posted:

My game's been out for ~50 days now and I haven't seen a single cent from it yet. :mad:

I'm in a similar spot except I didn't realise I needed photo ID to get money out and my passport will take 10 weeks to renew :(

Luckily I don't need the money right now!

Zaphod42
Sep 13, 2012

If there's anything more important than my ego around, I want it caught and shot now.

TooMuchAbstraction posted:

Well, now I'm pissed off at Steam. My game launched in the middle of July. Steam sends payments only once a month, on the 30th...and they also don't send any money that they haven't held onto for at least 30 days. Which is kind of scummy but I can see justifications for it (mostly around refunds). So I don't get any payment until August 30th.

In an astounding set of bad timing, my bank, BlueVine, did a big transition that involved changing their routing numbers, also timed for the 30th. I gave Steam the updated account information and hoped for the best...unfortunately they sent their payment early and so of course it failed. No big deal, I contacted them and asked them to try again. Response: no, we only send payments once per month, you'll have to wait another month. I pointed out that I'm a small dev, the launch money represents a significant amount of income for me, and the payment failed due to factors entirely outside of my control. Response: sorry, no, wait a month.

My game's been out for ~50 days now and I haven't seen a single cent from it yet. :mad:

:negative: dude that sucks, I'm sorry

Gin_Rummy
Aug 4, 2007

Ruzihm posted:

Good luck, and if you're interested in having the forward be in relation to the surface the cylinder is on, you should be able to use the surface's normal instead of Vector3.up.

A little slow swinging back around to this one, but it does not seem to be having the intended effect, though perhaps I am implementing it wrong.

So here is what I am running for my base position/velocity scheme:

code:
// set csys position = to player object transform's position
csys.position = this.transform.position;
// ensure csys is pointing "forward"
csys.transform.forward = Vector3.Cross(this.transform.right, Vector3.up);
// apply velocity locally in relation to csys (movementY is a float from earlier code; ultimate comes just from Unity's built in input control module)
movement = csys.transform.InverseTransformVector(new Vector3(0.0f, 0.0f, movementY));
// add velocity force to rigid body, speed is defined in the unity hub for the time being
rb.AddForce(movement * speed);
Unfortunately, I am still seeing the same issue... your assumption was correct in that I basically want to lock my csys "right" to the cylinder's "right," but the csys still fluctuates between pointing left and right despite the addition of the cross product. The velocity and position seem to be working properly (csys moves in lock step with the cylinder), but since my csys keeps spinning 180 deg, my velocity essentially keeps alternating between "forwards" and "backwards," thus leading to a rolling stall.

Gin_Rummy fucked around with this message at 21:06 on Sep 7, 2021

Ruzihm
Aug 11, 2010

Group up and push mid, proletariat!


Gin_Rummy posted:

A little slow swinging back around to this one, but it does not seem to be having the intended effect, though perhaps I am implementing it wrong.

So here is what I am running for my base position/velocity scheme:

code:
// set csys position = to player object transform's position
csys.position = this.transform.position;
// ensure csys is pointing "forward"
csys.transform.forward = Vector3.Cross(this.transform.right, Vector3.up);
// apply velocity locally in relation to csys (movementY is a float from earlier code; ultimate comes just from Unity's built in input control module)
movement = csys.transform.InverseTransformVector(new Vector3(0.0f, 0.0f, movementY));
// add velocity force to rigid body, speed is defined in the unity hub for the time being
rb.AddForce(movement * speed);
Unfortunately, I am still seeing the same issue... your assumption was correct in that I basically want to lock my csys "right" to the cylinder's "right," but the csys still fluctuates between pointing left and right despite the addition of the cross product. The velocity and position seem to be working properly (csys moves in lock step with the cylinder), but since my csys keeps spinning 180 deg, my velocity essentially keeps alternating between "forwards" and "backwards," thus leading to a rolling stall.

Ah, I don't expect this will solve the problem on its own but you don't want to use InverseTransformVector here. That converts from world to local. AddForce expects a world space input so you would want to use TransformVector instead.

code:
// set csys position = to player object transform's position
csys.position = this.transform.position;
// ensure csys is pointing "forward"
csys.transform.forward = Vector3.Cross(this.transform.right, Vector3.up);
// apply velocity locally in relation to csys (movementY is a float from earlier code; ultimate comes just from Unity's built in input control module)
movement = csys.transform.TransformVector(new Vector3(0.0f, 0.0f, movementY));
// or since you are only using the forward dimension:
// movement = csys.transform.forward * movementY;
// add velocity force to rigid body, speed is defined in the unity hub for the time being
rb.AddForce(movement * speed);
For shits & giggles what happens if you skip using csys and use a constant speed?

code:
movement = Vector3.Cross(this.transform.right, Vector3.up);
rb.AddForce(movement * 0.5f); // or appropriate factor if 0.5 is too low or high

Ruzihm fucked around with this message at 22:20 on Sep 7, 2021

Gin_Rummy
Aug 4, 2007

Ruzihm posted:

Ah, I don't expect this will solve the problem on its own but you don't want to use InverseTransformVector here. That converts from world to local. AddForce expects a world space input so you would want to use TransformVector instead.

Although it's wrong, it technically seems to work the way I am intending it to. Translating to world space means that my forward direction is not correlated to the direction of my transform in any way and my object always moves in the same direction, regardless of which way I turn it. I have tried it both ways and InverseTransformVector currently gives the desired motion.


Ruzihm posted:

For shits & giggles what happens if you skip using csys and use a constant speed?

Doing it this way doesn't seem to allow any forward movement. I haven't actually been able to get anything to happen unless my movement value is in the form of a vector with appropriate float values in the i, j, and k directions.

EDIT: I think it is because this doesn't actually pull the input (movementY) from the input manager, therefore it just sits frozen?

Gin_Rummy fucked around with this message at 22:34 on Sep 7, 2021

Ruzihm
Aug 11, 2010

Group up and push mid, proletariat!


Gin_Rummy posted:

Although it's wrong, it technically seems to work the way I am intending it to. Translating to world space means that my forward direction is not correlated to the direction of my transform in any way and my object always moves in the same direction, regardless of which way I turn it. I have tried it both ways and InverseTransformVector currently gives the desired motion.

Doing it this way doesn't seem to allow any forward movement. I haven't actually been able to get anything to happen unless my movement value is in the form of a vector with appropriate float values in the i, j, and k directions.

Very curious... can you post a screenshot of the local axes of whatever transform this.transform is referring to? preferably multiple at different rotations of the cylinder

Gin_Rummy
Aug 4, 2007
Sure, I’ll grab some screencaps when I get home. If it helps though, “this.transform” is my cylinder and player object. My movement script is attached to that object and that object alone.

Gin_Rummy
Aug 4, 2007
Here we go, made a little video capture to illustrate what is going on.

The first set of rotate/move you see if from the empty csys that follows my cylinder. (csys.transform)

The second set is the cylinder's csys. (this.transform)

https://imgur.com/a/ZWWbQZQ

Gin_Rummy fucked around with this message at 02:30 on Sep 8, 2021

Ruzihm
Aug 11, 2010

Group up and push mid, proletariat!


Aha!! I see the problem! It's the down of your cylinder's transform we should use as its right. Another change I think would be good to prevent issues caused by the cylinder's axis not being exactly horizontal is to use Quaternion.LookRotation to set the rotation of the csys exactly:

code:
// set csys position = to player object transform's position
csys.position = this.transform.position;
// ensure csys is pointing "forward"
csys.rotation = Quaternion.LookRotation(Vector3.Cross(-this.transform.up, Vector3.up));
// apply velocity locally in relation to csys (movementY is a float from earlier code; ultimate comes just from Unity's built in input control module)
movement = csys.forward * movementY;
// add velocity force to rigid body, speed is defined in the unity hub for the time being
rb.AddForce(movement * speed);
Or with your original use of InverseTransformVector (which is still a little weird to me :thunk: )

code:
// set csys position = to player object transform's position
csys.position = this.transform.position;
// ensure csys is pointing "forward"
csys.rotation = Quaternion.LookRotation(Vector3.Cross(-this.transform.up, Vector3.up));
// apply velocity locally in relation to csys (movementY is a float from earlier code; ultimate comes just from Unity's built in input control module)
movement = csys.InverseTransformVector(new Vector3(0.0f, 0.0f, movementY));
// add velocity force to rigid body, speed is defined in the unity hub for the time being
rb.AddForce(movement * speed);
Edit: Also I realized if csys is of type Transform you can just use csys.forward or csys.rotation and so on.

Ruzihm fucked around with this message at 08:21 on Sep 8, 2021

Gin_Rummy
Aug 4, 2007

Ruzihm posted:

Aha!! I see the problem! It's the down of your cylinder's transform we should use as its right. Another change I think would be good to prevent issues caused by the cylinder's axis not being exactly horizontal is to use Quaternion.LookRotation[.fixed] to set the rotation of the [fixed]csys exactly:

code:
// set csys position = to player object transform's position
csys.position = this.transform.position;
// ensure csys is pointing "forward"
csys.rotation = Quaternion.LookRotation(Vector3.Cross(-this.transform.up, Vector3.up));
// apply velocity locally in relation to csys (movementY is a float from earlier code; ultimate comes just from Unity's built in input control module)
movement = csys.forward * movementY;
// add velocity force to rigid body, speed is defined in the unity hub for the time being
rb.AddForce(movement * speed);

I think this is all good and better than what I had. I actually had to set movement = csys.right * movementY because of the way the csys is actually pointing (csys.forward gave me side-to-side motion). However, all that being said... my csys still flips around and does not seem to be "fixed" facing one direction. My back-and-forth rolling stall persists. :(

Ruzihm
Aug 11, 2010

Group up and push mid, proletariat!


Gin_Rummy posted:

I think this is all good and better than what I had. I actually had to set movement = csys.right * movementY because of the way the csys is actually pointing (csys.forward gave me side-to-side motion). However, all that being said... my csys still flips around and does not seem to be "fixed" facing one direction. My back-and-forth rolling stall persists. :(

This is very strange - the code works for me and I can't seem to account for why your this.transform is flipping like that. I can only guess there's another component or code making changes to things...

https://imgur.com/a/atScNL6
code:
using UnityEngine;

public class TestScript : MonoBehaviour
{
    [SerializeField] private Transform csys;
    [SerializeField] private float speed;
    private Rigidbody rb;

    private void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    private void Update()
    {
        float movementY = Input.GetAxis("Vertical");

        // Here instead of FixedUpdate for brevity
        csys.position = this.transform.position;
        csys.rotation = Quaternion.LookRotation(Vector3.Cross(-this.transform.up, Vector3.up));
        Vector3 movement = csys.forward * movementY;
        rb.AddForce(movement * speed);
    }
}

Ruzihm fucked around with this message at 16:40 on Sep 8, 2021

Gin_Rummy
Aug 4, 2007
Ok, it seems my player rotation code is causing the issue.

code:
    void FixedUpdate()
	{
	// tie csys position to player object's position
        csys.transform.position = this.transform.position;
        // point csys "forward"
        csys.rotation = Quaternion.LookRotation(Vector3.Cross(-this.transform.up, Vector3.up));

        
        // rotate csys with player object
        float playerRotation = movementX;
        transform.Rotate(playerRotation, 0, 0, Space.Self);
        float transformEuler = this.transform.eulerAngles.y;
        float csysEuler = csys.transform.eulerAngles.y;
        float deg = transformEuler - csysEuler;
        csys.transform.Rotate(0, deg, 0, Space.Self);

        // add velocity force to rigid body
        movement = csys.forward * movementY;
        rb.AddForce(movement * speed);
	}
From my previous video captures you can see that it works when stationary, but then for some reason adding the forward motion just screws everything up. Probably a bad move to assume that just because it works while stationary it wouldn't cause issues in motion...

I think the stuff you've guided me towards actually eliminates a need for most of what I still had there, so now it looks more like this:


code:
    void FixedUpdate()
	{
	// tie csys position to player object's position
        csys.transform.position = this.transform.position;
        // point csys "forward"
        csys.rotation = Quaternion.LookRotation(Vector3.Cross(-this.transform.up, Vector3.up));

        
        // rotate player object
        float playerRotation = movementX;
        transform.Rotate(playerRotation, 0, 0, Space.Self);

        // add velocity force to rigid body
        movement = csys.forward * movementY;
        rb.AddForce(movement * speed);
	}
Only problem is that now my rotation is very jerky and stalls in a similar way to how my forwards/backwards motion had been doing. It will turn X deg, then stall back and forth +/- Y deg.

EDIT: Actually, it works fine before any forward/backward motion is applied, but once the object is on the move everything goes haywire. Sometimes the turning directions will even flip as well... so I'll "turn left," then after moving forward a little bit more, "turn left" has suddenly become "turn right." However, this does not seem csys related, as both the cylinder object and the empty csys track the way they should, regardless of the state of motion.

Gin_Rummy fucked around with this message at 17:00 on Sep 8, 2021

Ruzihm
Aug 11, 2010

Group up and push mid, proletariat!


Gin_Rummy posted:

Only problem is that now my rotation is very jerky and stalls in a similar way to how my forwards/backwards motion had been doing. It will turn X deg, then stall back and forth +/- Y deg.

EDIT: Actually, it works fine before any forward/backward motion is applied, but once the object is on the move everything goes haywire. Sometimes the turning directions will even flip as well... so I'll "turn left," then after moving forward a little bit more, "turn left" has suddenly become "turn right." However, this does not seem csys related, as both the cylinder object and the empty csys track the way they should, regardless of the state of motion.

The problem there is that you are rotating around the local up which is constantly changing direction as it moves. Instead you could rotate around the csys's up:

code:
public class TestScript : MonoBehaviour
{
    [SerializeField] private Transform csys;
    [SerializeField] private float speed;
    private float movementX;
    private float movementY;
    private Vector3 movement;

    private Rigidbody rb;

    private void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    private void Update()
    {
        movementX = Input.GetAxis("Horizontal");
        movementY = Input.GetAxis("Vertical");
    }

    private void FixedUpdate()
    {
       
        // tie csys position to player object's position
        csys.transform.position = this.transform.position;
        // point csys "forward"
        csys.rotation = Quaternion.LookRotation(Vector3.Cross(-this.transform.up, Vector3.up));

        // rotate player object
        float playerRotation = movementX;
        transform.RotateAround(transform.position, csys.up, playerRotation);

        // add velocity force to rigid body
        movement = csys.forward * movementY;
        rb.AddForce(movement * speed);
    }
}
Alternatively, you could use Rotate(0f, playerRotation, 0f, Space.World); to rotate around the world up. But in the event you decide to use the surface normal instead of Vector3.up in the Cross to handle turning & moving while on a slope differently, using RotateAround in this way will take changes in the surface into account.

v :tipshat:

Ruzihm fucked around with this message at 18:05 on Sep 8, 2021

Gin_Rummy
Aug 4, 2007

Ruzihm posted:

The problem there is that you are rotating around the local up which is constantly changing direction as it moves. Instead you could rotate around the csys's up:

AH, yes! I think that is it. I think there are still many more fine tweaks that need to be made, but at its core this seems to have solved the issue! Thank you, miracle worker!

FunkyAl
Mar 28, 2010

Your vitals soar.
What's a good RPG engine/script that's good for beginners but gives you some wiggle room to do different stuff with the code

worms butthole guy
Jan 29, 2021

by Fluffdaddy

FunkyAl posted:

What's a good RPG engine/script that's good for beginners but gives you some wiggle room to do different stuff with the code

I tried this and it was.cool making your own rpg language out of lua

https://howtomakeanrpg.com/

But I'd like to see what real development people say lol

CH Science
Sep 11, 2019

I thought RPGMaker was supposed to be pretty legit nowadays.

If that doesn't have the features you need I'd almost say to just jump all the way to Unity or Godot or something.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
If you're going to do async gameplay logic (i.e. with actions that resolve over multiple frames) in the language you're looking for, then you want a language with coroutines. Python, Lua, and .NET all have them in some form or other.

If you're going for retro-style (and maybe even if not) then they're not really that complex to make from a technological standpoint. There's actually a lot of documentation reverse-engineering old Square RPGs, one of the major Wiki sites has the AI script for pretty much every monster you could fight, so you can look at stuff like that to figure out how they handled certain things.

The hard part is the huge amount of content that you need to make for them, which is one of RPGMaker's major upshots.

FunkyAl
Mar 28, 2010

Your vitals soar.
What I'm looking to do is mostly traditional, but I want to be able to experiment with things like battle machanics, like mother or mario and luigi, and also I just want to draw different camera angles in battles. I'm considering RPG maker, my question is just if it's flexible enough for that stuff.

Corbeau
Sep 13, 2010

Jack of All Trades
I am partway through implementing very basic editing support on my project so that the designer (and modders) can make changes without getting unto Unity guts. At this point they can add or alter pretty much any graphical or numerical element, but not (yet) dictate gameplay mechanics. Are there good resources that talk about designing and/or implementing limited scripting for modding? I don't exactly want mods that can execute arbitrary code, so whatever I'm implementing has to be limited and game-specific.

My brain is telling me that this isn't really that monolithic a challenge but I'm still having trouble finding my starting point.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
I'm musing on the design for my game's next mission. The plan for this mission is that the player sneaks into the Norway fjords, angers a big fleet, and then lures it back into a minefield. This feels like a fairly strictly ordered event sequence, so I need to figure out how to handle when the player invariably tries to take it off the rails.

For example, consider this area near Trondheim:



Let's imagine the player enters from the top-left area, and the fleet is in the relatively open waters in the center of the map. So the player sails into the middle area and angers the fleet by damaging it a bit. This should make the AI start "chasing" the player. However, my AI is utterly atrocious at navigating, especially if there's much land around. So actually having it chase the player would result in a bunch of ships blundering around and accomplishing nothing much. One thing the AI can do well is follow a series of waypoints...so hypothetically I could have the AI start chasing waypoints towards the minefield. And that would work well so long as the player always stays ahead of the fleet: they'd look like they were chasing the player, and once the player gets clear of the minefield, they'll blunder into it as expected.

However, I guarantee that at least 25% of my player base will hear "giant fleet that I'm not supposed to fight" and think "I am totally going to destroy this fleet singlehandedly". So the game needs to be able to handle the player standing their ground and fighting. It's straightforward enough to say "these ships have all got to die, and if it's the player's direct action that sinks them, then they get some bonus dialog and win anyways". But it's the AI I'm worried about. If the ships are coded to "start chasing the player" (i.e. follow waypoints), and then the player doesn't actually run away, then it will become clear to the player that the ships are ignoring them rather than chasing them as the flavor text promised.

I'm trying to figure out how to handle this without completely rewriting my AI steering logic, such as it is. For background, my AI supports the following behaviors:
  • Hold position
  • Follow a fixed heading
  • Spin in circles
  • Traverse a sequence of waypoints (which may optionally loop)
  • Try to travel in a straight line to a point near a target ship
While doing these, they also tell their guns to track and fire on their chosen target, and they have extremely rudimentary obstacle-avoidance logic that takes the form of "fire some raycasts forwards, if the rays hit something, back up, turn, and try again".

So one thing I could do would be to say "if more than X ships die, then the ships switch from follow-waypoints to chase-the-player, on the assumption that the player is standing their ground and trying to fight". That would fix the "enemy ships are ignoring me" problem I mentioned earlier. But then if the player goes "wait, poo poo, this is harder than it looked, I wanna try the minefield option after all", I have no way to get the AI ships back onto their waypoint behaviors. And they can't actually pathfind, so they'd all get hung up on the terrain.

Any suggestions? It's totally doable to add some scripting to this mission or to extend the AI in reasonable ways, but anything that requires the AI to actually be intelligent is almost certainly a non-starter.

...maybe I could write an AI mode that is "always stay on this waypoint sequence, but try to travel to the point on it that's closest to where the player is"? It'd be a basic navmesh, more or less, except it's always a line so the graph traversal is straightforward.

TooMuchAbstraction fucked around with this message at 02:34 on Sep 13, 2021

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

TooMuchAbstraction posted:

...maybe I could write an AI mode that is "always stay on this waypoint sequence, but try to travel to the point on it that's closest to where the player is"? It'd be a basic navmesh, more or less, except it's always a line so the graph traversal is straightforward.
What's wrong with just following a waypoint sequence to the waypoint that's closest to the player, so it actually follows the player as promised? Is it just that your navmesh doesn't have "find the shortest path" functionality? (Also presumably it should only follow if it can see you, so I would think it wouldn't require a very deep navmesh check.)

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

roomforthetuna posted:

What's wrong with just following a waypoint sequence to the waypoint that's closest to the player, so it actually follows the player as promised? Is it just that your navmesh doesn't have "find the shortest path" functionality? (Also presumably it should only follow if it can see you, so I would think it wouldn't require a very deep navmesh check.)

The current system isn't actually a navmesh, it's literally just "go to waypoint N, okay I reached that, now go to waypoint N+1". It allows me to set preprogrammed paths for ships, but has zero smarts in how they follow those paths.

This is not a game about stealth or smart enemies, so I'm not going to be worried about whether they can see the player. We can always assume they have radar, or high-flying scoutplanes, or someone on a hill with a telescope and a radio.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

TooMuchAbstraction posted:

The current system isn't actually a navmesh, it's literally just "go to waypoint N, okay I reached that, now go to waypoint N+1". It allows me to set preprogrammed paths for ships, but has zero smarts in how they follow those paths.
Ah, that makes sense. Then yeah, the thing you suggested at the end of your post seems like your best bet. You could maybe also have them backtrack if the player is behind them on the fixed route, like put them on a two-directional "rail". So long as the routes are narrow enough that should look like following the player.

TIP
Mar 21, 2006

Your move, creep.



Is there any reason you couldn't just have the player start dropping waypoints once they engage with the enemy?

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

Tip posted:

Is there any reason you couldn't just have the player start dropping waypoints once they engage with the enemy?

An interesting idea, but I can't help but feel like the work involved in getting it to behave itself would end up with it having the same net result as the "ships can target the point on their prescribed path that's closest to X". Like, when the player engages in combat, their path goes all over the place. So you need some way to simplify that path, lest you have a bunch of ships taking nonsensical twists and turns. But you also want to make sure that the simplified path doesn't cut any corners off of the terrain or get too close to the terrain in general, or else the ships will get jammed up.

Honestly, "programming" the ship behaviors in this game has been a great example of how to get something to be just not-lovely enough to pass casual muster. As long as the really terrible edge cases don't show up frequently, the player can generally excuse things as "oh ha ha ha those two ships ran into each other, isn't the AI stupid". If they show up frequently though, then the player may start thinking things like "man, this AI is dumb as rocks, it's really hurting my immersion". And watching a ship bonk into the terrain, back up a bit, then drive forward and bonk into the terrain again? You want that kind of thing to happen at most once per playthrough.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

TooMuchAbstraction posted:

\And watching a ship bonk into the terrain, back up a bit, then drive forward and bonk into the terrain again? You want that kind of thing to happen at most once per playthrough.
Ever Given.

Adbot
ADBOT LOVES YOU

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
I got the basic "chase the target while staying on the path" logic working pretty easily. Here's a bunch of enemy ships blundering into mines:

https://i.imgur.com/Z0u4fGt.mp4

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply