Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement radar code as a separate component #804

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

royfalk
Copy link
Contributor

@royfalk royfalk commented Oct 17, 2023

This PR introduces the concept of components - reactor, radar, cloaking device, etc.
This allows us to more elegantly move code from unit to components.
It will also allow for the removal of unit superclasses (e.g. movable) and easier upgrade, buy, sell, damage and fix components.

Let's use this to PR (and the cloaking one) discuss the concept of using components as a way forward.

Implement radar as a component.

Please answer the following:

Code Changes:

  • Have the PR Validation Tests been run? both standard and specific to radar.

Issues:

  • I was unable to damage and kill a Dgn Dodo at point blank. Other ships were affected. The guns locked just fine.
  • I think radar numbers are different from master. Need to verify this. Fixed.
  • The ship loses lock easy. This may have to do with the point above. If the lock cone is no longer 360 degrees, that would probably happen. Fixed.
  • The game crashes on startup. Game randomly crashes on new campaign startup (Radar PR) #1021. aeraturretadvtorpedo (also navpoint.blank and eject.template) have max radar range of 3b and not 300m.
  • Radar, like other components does not currently support repair via the standard button. Clicking it activates the old repair, which copies some stuff from the original upgrade. Clicking basic repair activates the proper repair function.

@royfalk royfalk self-assigned this Oct 17, 2023
@BenjamenMeyer
Copy link
Member

Yes, I like moving things to components. It makes a lot of sense.

Copy link
Contributor

@stephengtuggy stephengtuggy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I'm excited about this new componentized approach. I think that this is what we've been needing for a long time. I look forward to seeing where it goes.

Some of the refactors I have in mind will also be considerably easier if Unit doesn't inherit from 50 million things LOL

Also, convert radar to component standard
Disable radar energy draw for now - game doesn't support it yet.
Cones are in radian and aren't linear. They can't be stores in Resource.
@royfalk
Copy link
Contributor Author

royfalk commented Feb 6, 2025

PR is ready for testing. If you intend to test it, please modify aeraturretadvtorpedo in units.json to reduce Max_Cone to 300000000 (300k km). I'll test it over the weekend.

@BenjamenMeyer, @stephengtuggy - WRT to the explicit keyword in the constructor above, I'd like more guidance. I've looked at https://stackoverflow.com/a/121163/5276890 and I think I understand.

If I have Resource<double> , I can only instantiate it with a double, not an int. I'm not convinced this is in our interest. Resource really works with only ints and doubles. Do we not want the following to work?

int i = 8;
Resource<double> a = Resource<double>(i);

Also, my example was really of an implicit casting from int to double. Can you think of a scenario where an actual constructor is called? One where we don't want this to work. I'm not seeing the gotcha, that is surely there.

@royfalk royfalk changed the title [Draft] Implement radar code as a separate component Implement radar code as a separate component Feb 7, 2025
@royfalk royfalk requested a review from evertvorster February 7, 2025 07:57
@stephengtuggy
Copy link
Contributor

PR is ready for testing. If you intend to test it, please modify aeraturretadvtorpedo in units.json to reduce Max_Cone to 300000000 (300k km). I'll test it over the weekend.

@BenjamenMeyer, @stephengtuggy - WRT to the explicit keyword in the constructor above, I'd like more guidance. I've looked at https://stackoverflow.com/a/121163/5276890 and I think I understand.

If I have Resource<double> , I can only instantiate it with a double, not an int. I'm not convinced this is in our interest. Resource really works with only ints and doubles. Do we not want the following to work?

int i = 8;
Resource<double> a = Resource<double>(i);

Also, my example was really of an implicit casting from int to double. Can you think of a scenario where an actual constructor is called? One where we don't want this to work. I'm not seeing the gotcha, that is surely there.

@royfalk the explicit keyword is mostly just good practice in general. In practice, it would likely come into play only if a constructor or method takes a parameter of type Resource<int> or Resource<double>, and we pass a straight int or double instead. I don't know that we do that anywhere in the codebase as it stands today. It's more just a good habit to get into, I think.

@royfalk
Copy link
Contributor Author

royfalk commented Feb 8, 2025

@royfalk the explicit keyword is mostly just good practice in general. In practice, it would likely come into play only if a constructor or method takes a parameter of type Resource or Resource, and we pass a straight int or double instead. I don't know that we do that anywhere in the codebase as it stands today. It's more just a good habit to get into, I think.

I'm really on the fence here. On the one hand, it is considered good practice. On the other hand, the whole point of Resource is to elegantly wrap int/double. We have a whole bunch of overloaded operators for exactly that reason. I'll think about it some more.

@BenjamenMeyer
Copy link
Member

@royfalk the explicit keyword is mostly just good practice in general. In practice, it would likely come into play only if a constructor or method takes a parameter of type Resource or Resource, and we pass a straight int or double instead. I don't know that we do that anywhere in the codebase as it stands today. It's more just a good habit to get into, I think.

I'm really on the fence here. On the one hand, it is considered good practice. On the other hand, the whole point of Resource is to elegantly wrap int/double. We have a whole bunch of overloaded operators for exactly that reason. I'll think about it some more.

for now, let's skip the explicit keyword. Once we have more things as components we can revisit and see if it makes sense.

Copy link
Member

@BenjamenMeyer BenjamenMeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't play-test but things look okay to me

@royfalk
Copy link
Contributor Author

royfalk commented Feb 13, 2025

Pending #1016 merge.

- Add support for fixing radar
- Make max_range a resource
- Add better support for int and long resources
@royfalk
Copy link
Contributor Author

royfalk commented Feb 18, 2025

I'm going to hold off on merging this until Sunday or so to give people a chance to play test.

@evertvorster , @kheckwrecker
Please play test with this Assets PR: vegastrike/Assets-Production#160

@kheckwrecker
Copy link

kheckwrecker commented Feb 19, 2025

Safe to merge on top of PR #1036 for play testing?

return true;
}
break;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: This is where Polymorphism helps out since you could just do:

if (unit->Damaged()) {
    unit->Repair();
    return true;
}
return false;

since of having all the various switch cases. Now the generic Unit class probably isn't the right level to have that, perhaps a Component class would be. Hopefully that's where we're eventually heading.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort of, but it's a lot more complicated. This code is for components, which sub-class from Component, not Unit. What we need is for Component itself to be a sub-class of Cargo for this to work.
Except, even then, you'd probably need similar code to tie the GUI element to the Component.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think this is an example of preferring composition over inheritance, which I have seen recommended in several places recently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort of, but it's a lot more complicated. This code is for components, which sub-class from Component, not Unit. What we need is for Component itself to be a sub-class of Cargo for this to work. Except, even then, you'd probably need similar code to tie the GUI element to the Component.

yes, Unit certainly is the right place; it would be good if we could have this pointing at Component instead so we could do that. I'm sure we'll get there eventually.

@stephengtuggy for the language we work in (C/C++) inheritance is the right tool; we just need to get the codebase to where we can move away from everything using Unit and using more specific sub-classes appropriate to the different areas - in this case as @royfalk pointed out it's probably Component.

I do a lot of Go for other stuff; and Go uses Composition instead; at the end of the day it isn't really any different other than that the compiler has to enforce interface more. You can still end up with the same exact issues.

Copy link
Member

@BenjamenMeyer BenjamenMeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incorrect float implementation

@royfalk
Copy link
Contributor Author

royfalk commented Feb 19, 2025

Safe to merge on top of PR #1036 for play testing?

No. This should come before. #1016 has made significant changes and I now have to modify this and #1036 to match.

@kheckwrecker
Copy link

Please play test with this Assets PR: vegastrike/Assets-Production#160

Done. Looks good to me. The only comment I have is that the sensor (radar?) loses focus on occasion. For example, if I hit "n" to navigate to Serenity and start autopiloting there, my VDU would stay on that destination. With this version, it will occasionally switch off to targeting ships that are nearby. It's easy enough to switch back to my planned destination, but it's new behavior, so I thought best to report it. Otherwise, from flying around Cephid-17, looks good. Also, repairing and buying components for my ship worked as expected, as did Basic Repair and Refuel.

@royfalk
Copy link
Contributor Author

royfalk commented Feb 20, 2025

With this version, it will occasionally switch off to targeting ships that are nearby. It's easy enough to switch back to my planned destination, but it's new behavior, so I thought best to report it.

I've seen this as well. I'll have to think about it some more.

@kheckwrecker
Copy link

kheckwrecker commented Feb 21, 2025

Discovered a new problem while testing. Loaded my saved game, went to Ship Upgrade and my shields show damaged (at 99%) and the fix costs .70. Click on the fix button, and the credits are deducted, but the fix never happens. Can click on fix repeatedly and the credits go down each time, but the repair never happens.

Saved game attached.
Llama.begin.json

Edit: Just loaded saved game , and the fix on my shields worked fine this time. However, now my Llama is basically unflyable. I was on Atarxia and I picked a patrol mission. I had to scan Atarxia (the military base), but when I launched I was about 800 kilometers away (which was weird), so I turned around to point directly at it and engaged autopilot, with it showing in my VDU. My speed was jumping up and down like crazy, and I was actually accelerating away from my target, while pointed directly at it. So I turned around so it was behind me, but I continued to accelerate away from it at the same speed.

@royfalk
Copy link
Contributor Author

royfalk commented Feb 22, 2025

With this version, it will occasionally switch off to targeting ships that are nearby. It's easy enough to switch back to my planned destination, but it's new behavior, so I thought best to report it.

I think the game can't really lock on serenity because it's too far away (as it should) and when something closer comes along, it auto locks to it. Open an issue so we can make an exception to navigable stuff.

Discovered a new problem while testing. Loaded my saved game, went to Ship Upgrade and my shields show damaged (at 99%) and the fix costs .70.

Using your save game, I show damage but no fix button.

Click on the fix button, and the credits are deducted, but the fix never happens. Can click on fix repeatedly and the credits go down each time, but the repair never happens.

I'm not sure how you were able to do this, but I think I know what happened. The shield is somehow saved as 149/150/150. That means that it is currently 149 but it is not damaged. The code incorrectly uses the 149/150 percent to check if damaged. I'll fix this and see if it works for you.

WRT to auto pilot, this stuff sometimes happens but is unrelated to the current changes I made to the code. I was unable to reproduce. However, I often overshot Atraxia and the auto pilot had to turn around to get to it. I'm not sure why.
Can you reliably reproduce this with the save game?

@kheckwrecker
Copy link

With this version, it will occasionally switch off to targeting ships that are nearby. It's easy enough to switch back to my planned destination, but it's new behavior, so I thought best to report it.

I think the game can't really lock on serenity because it's too far away (as it should) and when something closer comes along, it auto locks to it. Open an issue so we can make an exception to navigable stuff.

Will do.

Discovered a new problem while testing. Loaded my saved game, went to Ship Upgrade and my shields show damaged (at 99%) and the fix costs .70.

Using your save game, I show damage but no fix button.

Click on the fix button, and the credits are deducted, but the fix never happens. Can click on fix repeatedly and the credits go down each time, but the repair never happens.

I'm not sure how you were able to do this, but I think I know what happened. The shield is somehow saved as 149/150/150. That means that it is currently 149 but it is not damaged. The code incorrectly uses the 149/150 percent to check if damaged. I'll fix this and see if it works for you.

Okay. Every time it happens now (and it happens regularly), I'm able to fix my shield back to 100%. Please let me know when the fix is ready for testing.

WRT to auto pilot, this stuff sometimes happens but is unrelated to the current changes I made to the code. I was unable to reproduce. However, I often overshot Atraxia and the auto pilot had to turn around to get to it. I'm not sure why. Can you reliably reproduce this with the save game?

Not reliably, unfortunately. I've seen it once more, but then it stopped in the middle of a flight and autopilot resumed as normal. I'll keep watching and see if I can spot a pattern.

- Calculate percent operational from shield damage and not shield strength. By shield damage I mean that the actual generator sustained damage and is not operating at a 100%. By shield strength I mean the value of the shields after they absorb damage.
- Calculate damaged from operational and not call percent. Operational is an internal variable that reports the percent the component is undamaged. Percent is a function that returns an average of the shield strength at the moment.
@royfalk
Copy link
Contributor Author

royfalk commented Feb 23, 2025

OK, so I think I figured out what happened. When you dock your ship, it automatically refuels and maxes out your capacitors (including FTL) and shields.
For some reason, the save game was saved with a value of 149/150/150 for shields.
First value means the current shield strength - that shouldn't be different from the second when we dock.
Second value is the temporary maximum - if the shield generator is damaged, this is lower.
Third value is the maximum. When we repair, first and second are equal to this.

I fixed it so illegal values like this will not impact the game. Please test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants