ID:1565616
May 3 2014, 2:34 pm
|
|
How do some of you handle keeping an object's icon_state up-to-date? I find myself having to use if more frequently than I would like to.
|
May 3 2014, 9:42 pm
|
|
Would you mind elaborating it a bit more, what do you mean by that?
|
In response to Taitz
|
|
For example:
src.icon_state = animation Here, I am making sure the mob's state is still in dash mode (I wouldn't want to mess up another animation, like a stun for example). |
You don't need the if(src). If the atom has been deleted, the spawned code won't execute in the first place.
|
In response to Topkasa
|
|
Topkasa wrote:
You don't need the if(src). If the atom has been deleted, the spawned code won't execute in the first place. Unless the function has been cut off from the src scope and forced into the global scope by: src = null Of course, that's not the case in FKI's example there, as he's still accessing src. |
In response to Topkasa
|
|
Good to know, but that's beside the point.
|
I wouldn't bother worrying about the icon_state, and just consider it an artifact of behavior.
I like to consolidate behavior into datums, and restrict mobs to a single action at a time. This way, I can store as much or as little information about an action as I want. mob action A quick, somewhat complicated implementation to demonstrate their use. In this example, we're allowing players to Move once per frame only. We have also implemented a few interesting situational effects. For starters, if a player is stunned, this counts as an action, because a player can't do anything else while stunned. Side note: I wouldn't recommend all of your status conditions being actions, because things like poison, polymorph, confusion, to name a few might allow the player to continue acting. Those types of things would need to be implemented separately from actions. In this setup, status ailments like Sleep would actually work really well, because any time a player is attacked, you can apply a Stunned action. Since actions replace the old action on the record, the player would wake up out of Sleep automatically if attacked in our setup. We have given the player two attacks. One is a regular attack, which hits everything within a bounding box the size of the player in the direction they are facing, and knocks them back 2 steps, and stuns them for 2 frames. If the player uses an attack on the same frame that they have moved, they will attempt to charge in the direction they are moving. This boosts them forward by 10 steps, and hits anything along that path. The impact with the player also imparts a knockback and stun of 10 steps plus however many steps the player has left in their charge, as well as stuns them for 10 ticks plus however many steps the player has left in their charge. Should the player hit anything that doesn't move out of the way over the duration of this attack, the player will be stunned himself for the remaining number of ticks the attack would have occurred during. The correct use of the action states allows you to take precise control of animations, visual changes, and even game behavior. Used correctly, you will have a very solid-feeling combat system at your disposal, and you won't ever have to worry about weird bugs cropping up due to attacks being canceled early, functions happening twice in rapid succession, etc. #define TICK_LAG 1 Does that answer your question a bit better, FKI? (I took the liberty of writing this to work with pixel movement AND tiled movement, since I know you've taken the journey toward learning how to pixel movement. To tie this in to my movement loop/edge sliding system, you'll have to do a bit of tweaking. If you have any trouble with that, give it a shot and let me know what you are having trouble with via PM.) |
Further side-notes:
If the player's connection dies while an action is not idle, don't let the player's mob be deleted. Action has been set to tmp. If you have an action that should persist through logging out, I suggest to you that you are doing it wrong. If you ever reach null reference errors in an action, the action is likely programmed correctly. The error is originating from an unsafe manual object deletion you did elsewhere in your code. Secondly, there's a side-effect of the control variable. Since control defaults to src, the object will never be garbage collected until you break the self-reference. If you want to allow the object to be swept up by the garbage collector, you need to, at some point, set control back to null. This won't change manual deletion, but I strongly urge developers to avoid explicitly calling del on any objects at all. It's lazy, can cause massive CPU issues, and if you don't take care, you can wind up with memory leaks. This is why paying attention to your memory management from the get-go is all-important. |
Nice read.
I don't use del at all except for deleting mobs after you disconnect (I couldn't get this to work with garbage collection, the mob was still being used when the player reconnected). |
In response to Ter13
|
|
Slightly off-topic, do you have any good reads on garbage collection design patterns?
|
More for *remembering* to null your references. I mean, is it something that you just need to make sure you're doing it yourself, or is there particular practices that can be followed to ensure proper cleanup without thinking about where it has been set?
An example of which would be using scope to allow all references to be erased when you're out of scope. |
Well, it's essentially just a logical matter of when you're not using it, that's it. All registers / adds have a corresponding unregister / remove. Once hooked around Login/Logout, you're pretty much golden.
This isn't a particularly mind-boggling task, for the most part. |
I suppose I should tack on, the reason I'm saying this is that the more complex you make a task out to be to beginners, the more likely it'll be over-thought, considered too difficult for them to do etc, and so, the less likely it happens.
It's common sense. Want stuff to tidy up automatically? Make sure you've not still got it in a variable or list somewhere. Wanna make sure it's not still in a variable or list somewhere? Ask the question "what happens to this when I'm done with the attack, or when the user logs out?" and write code accordingly. |
In response to Stephen001
|
|
Stephen001 wrote:
I suppose I should tack on, the reason I'm saying this is that the more complex you make a task out to be to beginners, the more likely it'll be over-thought, considered too difficult for them to do etc, and so, the less likely it happens. I fully agree with Stephen on this. Though, there are some corner cases for videogames in particular where it's necessary to avoid direct referencing of objects in order to avoid problems. In some areas, it's better to abstract a reference to an object and sacrifice speed for the sake of a look-up, or to store a user vector and inform them of an object no longer being in a useful context. However, that's really not a topic I'm not interested in teaching, as I know it'll be used in areas where it's not useful should I push the example out to this community. |
I know what you mean. I am very OCD about the code I write, often restarting as a result.
|
Doing it right the first time is easier than doing it wrong and refactoring later.
It's funny, that six months ago, most of the complaints about my advice is that it would "cause lag", or that BYOND "couldn't handle" what I claimed it could. Then I proved it could, and everybody's complaints are that my examples are needlessly complicated. Haters gonna hate. |
You're not wrong, Walter.
I think a compromise between your approach and mine would definitely be effective. After all, Epic: Legend saw a very promising initial release, but all the problems of fast development stacked up on you immediately thereafter. Paying better attention to design considerations could have helped you, and not over-complicating things could well help me. |
In response to FKI
|
|
FKI wrote:
I know what you mean. I am very OCD about the code I write, often restarting as a result. Ugh, I know exactly what you mean. I was told to not fix what isn't broken once, but I find myself rewriting and repairing old programming ALL the time. Several projects have been restarted because of this. |