This video is like a hidden gem. I've worked in the game industry for five years, but I've always felt there were areas where I was lacking. I've learned so much from this channel. 🥰
@@git-amend Regarding the approach of using the StatsMediator and constantly updating the Stats each tick, isn't it more computationally intensive to work this way instead of using events, and wait until the duration of the modifier has finished to recalculate the stats once? which do you consider to be more efficient?
Thank you! This is so valuable! Have been working on a project that structures are super chaotic and very hard to read, knowing how to refactor is a life changer.
Great video! I once again learned a ton. If you would ever consider writing an (e)book explaining software architecture principles in the context of Unity, I'd buy it in a heartbeat ;)
Something I've been learning the hard way. It is MUCH easier to write bad code, then refactor it, then it is to write 'good code' from the start. I spent 5 hours rewriting the same movement script. I should just make something that works and come back to it later.
Always be cautious with wrapping. It always look like a dirty easy fix as we "only" need to add logic on top of existing logic and maybe make some fields protected and whatnot, but in the long term it over complexify everything. I had to wrap a whole lot of non-networked classes into networked classes once to not break offline parts of an app and, let me tell you, it was not a fun time to refactor and orient oneself into the whole project afterward.
I may have been doing some of this without knowing the official terms for it and I have had painful experience with refactoring too much at a time, losing way too much because what you thought was inefficient or pseudo code contained the logic for something else that you really needed. Also I think proper documentation is required even for your own code. Coming back to it after a while can have you hunting through your code trying to make heads or tails as to what you were doing. Just my experience.
Thank you! I've been a career software engineer my entire adult life, which has now been more than 2.5 decades, but I actually wrote my first program about 10 years before that.
Me and colleague had to refactor a single script for a client that held the logic for the ENTIRE app. It was also 3 methods, one being a 52 else if statement that did different things depending on the name of the button being pressed (did a string compared) T-T
This is fantastic! Any recommendations on which strategies to use to apply limits to the stats (defense maxes out at a value for example) or entirely skip modifiers (some debuff temporarily omits attack bonuses for example)?
Good question. I think there are a few ways to go about all of those things. I think it really depends on the game, but you might - for simplicity - just clamp them before returning each property in the Stats class getters. But of course, any upper limit might very over time or as the game progresses, so that might involve another strategy that could be handled by the Mediator as well. I think more complex scenarios might require another refactoring, and I'd have to give it a bit of thought before introducing any changes.
How are you viewing the stat changes from the UI ? Are you calling every frame in update to the attack and defense properties for changes?? or are you using some other more effecient method? is that effficient?
Great video as always, do you plan to record a generic UI Manager or UI / Popup management? I think this topic is a problem for a lot of game devs to manage them in a generic / modular way.
@@git-amend For example I am creating a popup manager where we access popups by dictionary, But i couldnt decide which way i should create the KEY. For now, I created the dictionary as which we give type in generic and get the popup. The problem is if we have same popup classes with different prefabs, it wont be able to register since the type is already added to dictionary. So how can i identify which popup I want as best practise/generic way? Should i pass a custom struct that includes Type and id variable, but then it will be kinda hard to find my popup from where i get, i need to give struct params and search my key list and find the required one. ENUM way is kinda bad for me too. What do you think about that ```cs private readonly Dictionary _popupMap = new Dictionary(); public T TryGetPopup() where T : BasePopup { if (!_popupMap.ContainsKey(typeof(T))) { Debug.LogWarning($"Popup {typeof(T)} is not registered."); return null; } return (T) _popupMap[typeof(T)]; }```
@@git-amend I am creating a popup manager where we access popups by dictionary, But i couldnt decide which way i should create the KEY. For now, I created the dictionary as which we give type in generic and get the popup. The problem is if we have same popup classes with different prefabs, it wont be able to register since the type is already added to dictionary. So how can i identify which popup I want as best practise/generic way? private readonly Dictionary _popupMap = new Dictionary(); public T TryGetPopup() where T : BasePopup { if (!_popupMap.ContainsKey(typeof(T))) { Debug.LogWarning($"Popup {typeof(T)} is not registered."); return null; } return (T) _popupMap[typeof(T)]; }
@@TheKr0ckeR Ok I see, I'll give that some thought. As to your comments being deleted, I can see one that is being held for review but I'm not sure why... it doesn't seem inappropriate!
I think it's amazing. I'm a beginner who does implementations mostly in singletons, and I learn there are these ways by looking at your code. I'm curious, do you build all the architecture from scratch and implement the game?
Thanks! Like most people, I start with a simple prototype. Then I have a better idea of how to structure a project. Then I just continue to iterate and refactor.
@@git-amend oh.. very difficult process. It's amazing that a skilled person like you is still like that. While watching your lecture, I am also revising the Stat system,I'm surprised to hear that you're also starting with a small project.
@@AriyaBayat I have a little bit, but I think I might try to combine it with techniques that are a bit more general. Another viewer asked me a while ago to do a video about Lionhead Studio's Black and White magic system which relies on pattern matching. This is actually very similar to a project I made a while back to help people learn languages like Korean and Japanese in VR, by pattern matching movements. So, it's a technique that applies to VR and normal games. Not sure exactly when yet, but it is on my list.
@@git-amend Cool I just checked it out now, and man those creatures look goofy 😂 But that's cool and the VR tech looks ahead of its time. I'm only asking because it seems that Unity is doubling down on all the XR stuff and I'm sure these optimisation techniques are still applicable for those kinds of projects like you say
Since you brought up unit tests - do you have a video on that already? I don't really understand the purpose of them as opposed to just playing through your game. "If an error occurs and no one's around to see it, is it really an error?" To me, the idea of unit tests seems like doubling the workload for no real benefit, but more advanced devs keep telling me they're essential. If you don't have a video already, could you perhaps consider making one and explain it like I'm five? As if I've never heard of a unit test before or how it's better than spot testing like how you tested your refactors by walking around in play mode?
Just imagine your computer playing through your game very very fast and reporting when things don't go as expected. This might seem like double work at first, but when your game gets increasingly larger, testing everything starts to take more and more of your time, so writing tests starts to pay off on the long run. It also makes me feel more confident in my code
@SanderDecleer Sure but I have to code it to look for specific things whereas I might catch something even I wasn't planning on testing for, and if I can't plan for it, I can't write a unit test for it.
You should absolutely still play your game to find such cases. When you eventually find one, make a failing test for it, then fix it. That makes sure you never need to worry about it again. Especially handy in situations where the reproduction is not trivial.
@@MarushiaDark316 the purpose of Unit Test is to make sure what is already passed the test will pass the test again, if not, it will inform you immediately to avoid side effect. There will cases like random bug (hard to reproduce) because chain of side-effect
Hello! Thank you so much for your videos, I would like to know your list of books that I should read to improve my skills, I would really appreciate it!
Thanks! If you join the Discord and go to the programming channel there is a pinned comment with my list of recommended books to read from beginner to advanced!
I can see you have integrated Copilot deeply in your workflow, how was the experience so far? And can it replace a junior dev rn:)) just ask for fun, this kind of question appears 10 times a day on my Reddit newfeed
I suppose it could replace a Junior, but it really depends. Like a Junior, it makes a lot of mistakes, and it cannot abstract solutions to large complex systems.
7 месяцев назад
@@git-amend IMHO the purpose of a junior is not to write code so much as to grow into a senior. Hopefully, copilot will make this process quicker and more painless, but there is a risk that it prevents learning by doing things "the old-fashioned way". I'm currently hopeful though!
Happy Sunday!!! Let me know YOUR pain points are when it comes to refactoring your own code (or someone else's) in the comments below! 👍
One of my biggest pain points is not doing it sooner and waiting for scope creeps to kick in and leaving a bigger mess to untangle.
This channel is pure gold. I am using Unreal and not Unity but I still learn a lot by watching your videos!
Great to hear!
Same
This video is like a hidden gem.
I've worked in the game industry for five years, but I've always felt there were areas where I was lacking.
I've learned so much from this channel. 🥰
I'm glad to hear that! Keep on learning!
Man, your content is awesone! It is so advanced, it's kicking my begginer/intermediate gamedev butt... 😂
Thanks! Always more to learn!
@@git-amend Regarding the approach of using the StatsMediator and constantly updating the Stats each tick, isn't it more computationally intensive to work this way instead of using events, and wait until the duration of the modifier has finished to recalculate the stats once?
which do you consider to be more efficient?
Thank you! This is so valuable! Have been working on a project that structures are super chaotic and very hard to read, knowing how to refactor is a life changer.
Great glad to hear that!
@@git-amend Also thank you for recommending the book!
Great video! I once again learned a ton. If you would ever consider writing an (e)book explaining software architecture principles in the context of Unity, I'd buy it in a heartbeat ;)
Great suggestion! Maybe one day!
Ditto!
This channel is amazing! Please keep all of it coming.
Thank you! Will do!
Thanks for the very nice video! Now its the perfect time to make a video about Unity Tests :)
Haha! We’ll see!
Something I've been learning the hard way. It is MUCH easier to write bad code, then refactor it, then it is to write 'good code' from the start. I spent 5 hours rewriting the same movement script. I should just make something that works and come back to it later.
I hear ya on that one! 💯
video on procedural level generation would be great. Thank you for the great video btw.
Great suggestion! Thanks!
Thank you for the all your videos!
Glad you like them!
Thanks for this one it will help ppl alot. Since you showed me strangler fig earlier this week i sliced 4 systems out of my prototype manager class!
Excellent! I’m glad it’s helping!
Yay, finally a new video! I don't know if it's just me, but I eagerly await Sundays for Git amend videos...
Thanks!
Always be cautious with wrapping.
It always look like a dirty easy fix as we "only" need to add logic on top of existing logic and maybe make some fields protected and whatnot, but in the long term it over complexify everything.
I had to wrap a whole lot of non-networked classes into networked classes once to not break offline parts of an app and, let me tell you, it was not a fun time to refactor and orient oneself into the whole project afterward.
Thanks for sharing your experience! I'm sure those words of caution are warranted.
I may have been doing some of this without knowing the official terms for it and I have had painful experience with refactoring too much at a time, losing way too much because what you thought was inefficient or pseudo code contained the logic for something else that you really needed. Also I think proper documentation is required even for your own code. Coming back to it after a while can have you hunting through your code trying to make heads or tails as to what you were doing. Just my experience.
Thanks for sharing. I agree, documentation is an essential part of development.
amazing video, keep it up
Thanks, will do!
This is... brilliant. Thanks a lot.
You're very welcome!
How long have you been programming for? You're very articulate with the way you speak. Very valuable content!
Thank you! I've been a career software engineer my entire adult life, which has now been more than 2.5 decades, but I actually wrote my first program about 10 years before that.
This is exactly what I needed..
Fantastic!
If you haven’t already, a video on unit tests would be great.
I have this video here you might like, it's an introduction to unit testing: ruclips.net/video/Wh27sG0DXzU/видео.html
A solid economy system for next video would be awesome!
Thanks for the idea! Maybe not next week, but I'll put that on the list.
Me and colleague had to refactor a single script for a client that held the logic for the ENTIRE app. It was also 3 methods, one being a 52 else if statement that did different things depending on the name of the button being pressed (did a string compared) T-T
Hahah... sheesh.
This is fantastic! Any recommendations on which strategies to use to apply limits to the stats (defense maxes out at a value for example) or entirely skip modifiers (some debuff temporarily omits attack bonuses for example)?
Good question. I think there are a few ways to go about all of those things. I think it really depends on the game, but you might - for simplicity - just clamp them before returning each property in the Stats class getters. But of course, any upper limit might very over time or as the game progresses, so that might involve another strategy that could be handled by the Mediator as well.
I think more complex scenarios might require another refactoring, and I'd have to give it a bit of thought before introducing any changes.
How are you viewing the stat changes from the UI ? Are you calling every frame in update to the attack and defense properties for changes?? or are you using some other more effecient method? is that effficient?
git-amend MVP
Thank you!
Great video as always, do you plan to record a generic UI Manager or UI / Popup management? I think this topic is a problem for a lot of game devs to manage them in a generic / modular way.
Possibly - can you have a specific scenario in mind?
@@git-amend For example I am creating a popup manager where we access popups by dictionary, But i couldnt decide which way i should create the KEY. For now, I created the dictionary as which we give type in generic and get the popup. The problem is if we have same popup classes with different prefabs, it wont be able to register since the type is already added to dictionary. So how can i identify which popup I want as best practise/generic way? Should i pass a custom struct that includes Type and id variable, but then it will be kinda hard to find my popup from where i get, i need to give struct params and search my key list and find the required one. ENUM way is kinda bad for me too. What do you think about that
```cs
private readonly Dictionary _popupMap = new Dictionary();
public T TryGetPopup() where T : BasePopup
{
if (!_popupMap.ContainsKey(typeof(T)))
{
Debug.LogWarning($"Popup {typeof(T)} is not registered.");
return null;
}
return (T) _popupMap[typeof(T)];
}```
@@git-amend I am creating a popup manager where we access popups by dictionary, But i couldnt decide which way i should create the KEY. For now, I created the dictionary as which we give type in generic and get the popup. The problem is if we have same popup classes with different prefabs, it wont be able to register since the type is already added to dictionary. So how can i identify which popup I want as best practise/generic way?
private readonly Dictionary _popupMap = new Dictionary();
public T TryGetPopup() where T : BasePopup
{
if (!_popupMap.ContainsKey(typeof(T)))
{
Debug.LogWarning($"Popup {typeof(T)} is not registered.");
return null;
}
return (T) _popupMap[typeof(T)];
}
@@TheKr0ckeR Ok I see, I'll give that some thought. As to your comments being deleted, I can see one that is being held for review but I'm not sure why... it doesn't seem inappropriate!
@@git-amend I think passing string ot enum is the fastest way though i am not sure its the best way
Engeneir's first rule: if it works, do not touch...
I think it's amazing. I'm a beginner who does implementations mostly in singletons, and I learn there are these ways by looking at your code.
I'm curious, do you build all the architecture from scratch and implement the game?
Thanks! Like most people, I start with a simple prototype. Then I have a better idea of how to structure a project. Then I just continue to iterate and refactor.
@@git-amend oh.. very difficult process. It's amazing that a skilled person like you is still like that.
While watching your lecture, I am also revising the Stat system,I'm surprised to hear that you're also starting with a small project.
Is there anyway i can support you? Because your content is incredibly useful
Sure, there is a link to my Ko-Fi page in the video description! Cheers!
@@git-amend Supported! Also, have you thought about doing anything on VR/AR in Unity?
@@AriyaBayat I have a little bit, but I think I might try to combine it with techniques that are a bit more general. Another viewer asked me a while ago to do a video about Lionhead Studio's Black and White magic system which relies on pattern matching. This is actually very similar to a project I made a while back to help people learn languages like Korean and Japanese in VR, by pattern matching movements. So, it's a technique that applies to VR and normal games. Not sure exactly when yet, but it is on my list.
@@git-amend Cool I just checked it out now, and man those creatures look goofy 😂
But that's cool and the VR tech looks ahead of its time. I'm only asking because it seems that Unity is doubling down on all the XR stuff and I'm sure these optimisation techniques are still applicable for those kinds of projects like you say
Do you have a plan for teaching ECS?
Yes, one of these days when time permits.
Since you brought up unit tests - do you have a video on that already? I don't really understand the purpose of them as opposed to just playing through your game. "If an error occurs and no one's around to see it, is it really an error?"
To me, the idea of unit tests seems like doubling the workload for no real benefit, but more advanced devs keep telling me they're essential. If you don't have a video already, could you perhaps consider making one and explain it like I'm five? As if I've never heard of a unit test before or how it's better than spot testing like how you tested your refactors by walking around in play mode?
Just imagine your computer playing through your game very very fast and reporting when things don't go as expected.
This might seem like double work at first, but when your game gets increasingly larger, testing everything starts to take more and more of your time, so writing tests starts to pay off on the long run.
It also makes me feel more confident in my code
@SanderDecleer Sure but I have to code it to look for specific things whereas I might catch something even I wasn't planning on testing for, and if I can't plan for it, I can't write a unit test for it.
You should absolutely still play your game to find such cases. When you eventually find one, make a failing test for it, then fix it. That makes sure you never need to worry about it again.
Especially handy in situations where the reproduction is not trivial.
There is a video on the channel about Unit Testing, it's in the Architecture playlist, it will help you with getting started if you are interested.
@@MarushiaDark316 the purpose of Unit Test is to make sure what is already passed the test will pass the test again, if not, it will inform you immediately to avoid side effect. There will cases like random bug (hard to reproduce) because chain of side-effect
Hello! Thank you so much for your videos, I would like to know your list of books that I should read to improve my skills, I would really appreciate it!
Thanks! If you join the Discord and go to the programming channel there is a pinned comment with my list of recommended books to read from beginner to advanced!
Rule #4 is "Yes, you should be unit testing" 😁
💯
I can see you have integrated Copilot deeply in your workflow, how was the experience so far? And can it replace a junior dev rn:)) just ask for fun, this kind of question appears 10 times a day on my Reddit newfeed
I suppose it could replace a Junior, but it really depends. Like a Junior, it makes a lot of mistakes, and it cannot abstract solutions to large complex systems.
@@git-amend IMHO the purpose of a junior is not to write code so much as to grow into a senior. Hopefully, copilot will make this process quicker and more painless, but there is a risk that it prevents learning by doing things "the old-fashioned way". I'm currently hopeful though!
@ I agree completely!
Hey, love the tutorials, please keep it up.
Im curious though, what happpened to equipable?
💥💥💥💥
Thanks!
Nice.
Thanks!
@@git-amend Congrats on 9K.
@@damonfedorick Thanks! Been a very interesting journey so far, and not long until the channel will cross that 5 figure number!
Refactoring is the best way you can make your game better even improve your skills. you can't write best when you start
💯