Jump to content
  • Advertisement

Galaban

Member
  • Content Count

    8
  • Joined

  • Last visited

Community Reputation

100 Neutral

About Galaban

  • Rank
    Newbie
  1. That does make a fair bit of sense. The issue is that these events are discrete as far as the internal game logic is concerned. There are events that can trigger off CastSpell (regardless of whether it does damage, or even accomplishes anything useful, such as counterspells or magical feedback), and events that can trigger off RecieveDamage (regardless of what sort of attack triggered this, such as damage reflection or self-buffs when injured). Even if the view only receives events organized into a format more useful to it (as you suggest above), the model needs to deal with them at a more discrete level, so SOME part of the code still has to sift through messages of different types and combine them, which seems to leave me with the original problem. Moreover, certain reaction abilities need to interpose themselves in the middle of the animation of the triggering spell. For example, consider a magic repulsion field that can redirect spell projectiles to other locations. The visualization of this should show the fireball being cast and moving towards its intended destination, then when it reaches the edge of the field, the activation of this field should be displayed, and the fireball projectile should continue onto its new location before exploding. Not only does the visualization of one effect (the repulsion field) need to be scheduled at a specific time, dependent on the visualization of the spell triggering it, but it needs to modify the actual visualization of a different spell. I hope it doesn't sound like I'm just constantly moving the goal posts here; I appreciate the comments, and I've found them to each contain things worth thinking on.
  2. Perhaps I am misunderstanding, but are you saying you consider it inappropriate for there to even BE events like RecieveDamage, given that they contain information other than source/target (ie: damage type and amount)? If so, why? They are distinct events that can have individual consequences (such as triggering counterattacks or other reaction abilities) regardless of their source. Ok, well that's a problem of maintaining state within your game objects, and something you should keep seperate to your events system. [/quote] In this case, perhaps not. I probably should have made it clear from the beginning, but this game is turn-based. Thus, as far as the game logic is concerned, there IS no delay between the initiating of an attack and its results. Proper scheduling of casting and damage thus cannot be handled by inserting real-time delays between when events are fired; CastSpell and RecieveDamage events will always be received effectively simultaneously by the view.
  3. Thanks for the code sketch and I will admit that me overthinking things is totally possibly, but I think I may still have a few issues. I agree in general, though I still wonder how to properly schedule animations involving a series of events. The code above seems to suggest that the animation for the spell cast is performed via GraphicsController::OnCastSpellEvent and then damage numbers are displayed after this is finished via GraphicsController::OnDamageTakenEvent. However, there is a specific point in the fireball animation where damage should be displayed and this point is not after the entire animation is finished. Moreover, the proper point might be in different places for different spell animations. This is especially true for things which score multiple hits, or hit multiple targets in sequence. For example, a piercing projectile attack should display the damage numbers over each target's head as the visualization of the projectile passes through them. The DamageTaken events themselves would have no idea how to properly stagger the time of their appearance; this information would only be possible to calculate when the spell that caused this damage is known.
  4. I'm sketching out the design of my game messaging system and find myself unsure of how the implementation details of the Message class and the distinctly different member variables needed for different types of events. In general, the is a very clear seperation between the model of the game and its view. Commands are sent from the controller to the model, all internal calculations regarding the effects of these commands are calculated within the model, and a sequence of messages is sent to all registered subscribers. The view recieves these messages and uses them to calculate what it should display to represent an action. These events can also be piped to, say, the displayed combat log or a module for saving replays. When considering the design of a Message class, it's fairly clear the different times of events require different parameters. A castSpell event requires a caster, the spellID, intended targets, and so forth. A recieveDamage event requires the recipiant, amount of damage, damage type, and possibly other flags indicating whether it was a critical hit and so forth. As I understand it, older methods of using a switch statement on a messageType parameter so that the message handler knows how to handle each class of message (or using RTTI to similar effect) are considered bad form, in favor of more proper use of the message's inherant polymorphism. Of course, one cannot put the handling routines in the message themselves, since the same message will be handled differently by different subscribers (eg: the game view vs. combat log vs. replay recorder). From what I read, this is where double dispatch tends to be used, routing each specific subclass of message to its own handling routine (eg: doCastSpell, doRecieveDamage, etc.) A problem with double dispatch in this case is that events are not strictly atomic. Well, perhaps that's not strictly true; each event instance passed does represent a discrete event, but in many cases these events are part of a larger event. For example, say that a unit casts a fireball spell and damages a number of units with it. This single action (casting fireball) results in a sequence of events, eg: castSpell(caster, fireball, targets) recieveDamage(target1, 15, fire) recieveDamage(target2, 12, fire) recieveDamage(target3, 21, fire) In order for the view to properly display the results of this action, it needs to read multiple message in a row (in this case, so that it knows what damage numbers to display over each unit when the fireball animation explodes, although there are more complex instances of this). If each message was routed to a seperate handling function (such as via double dispatch), it seems like this would be significantly trickier to do. The visualization of a recieveDamage event on its own is a meaningless concept; it can only be properly scheduled in the context of the larger sequence of events. Does this mean that, despite the code smell associated with switch-on-class-type, I might indeed be better off using such an approach, if the handling of one message requires knowing subtypes of subsequent messages? Is there a more elegant approach that I am overlooking here? Any feedback or suggestions would be welcome.
  5. Reasonable enough, really. So much of development is about making tradeoffs, anyway: performance vs. flexibility, and so forth. In the end, saving a couple hundred KB probably isn't worth the additional code complexity of encapsulating property groups, checking a half-dozen things for null references each frame, and creating/destroying property classes as effects become active or inactive. Even when this extra memory is almost entirely a result of overhead known to be unnecessary ahead of time in the general case. It may simply be the cost of avoiding something potentially worse. I had hoped there might be some obvious alternate way to go about this, but if not... Nearly all the source code I've perused to examine their rendering systems either had sprites that were much less flexible and capable in the first place, or legitimately needed most of their extended properties for the majority of their sprites. But it's probably better to err on the side of flexibility and clarity than worry about memory that is probably largely an ideological concern at this point.
  6. I considered this. The main issue in this case is that while I know that most sprites will not need any extended properties at any given time, I don't easily know in advance which of them will need them. For example, consider a motion trail effect that can be applied to any moving sprite. This is only used for certain special attack and spell animations, but these could theoretically apply to any creature or projectile. It's just that, in practice, 99% of creature and projectile sprites will never use it. The same thing applies to a great many of the extended properties. Given that I can't make very good advance judgments about when to give a creature a (for example) BasicSprite over an ExtendedSprite, this would seem to require a way to construct an ExtendedSprite from a BasicSprite (and vice versa), and convert a creature's sprite from one to the other whenever advanced effects are applied to it or when those advanced effects end. This... seems unpleasantly cumbersome, to say the least. The fact that a platform itself is inefficient doesn't mean that one should disregard efficiency entirely. If anything, it might be even more important since there are many ways to incur overhead. While you make an interesting point about 'free' memory within the allocated heap size, texture memory actually resides outside the JVM entirely (and isn't garbage-collected, etc.) So even if I did have 250MB of textures (In practice, I would have much, much less), this wouldn't buy any 'free' heap space to use for other purposes. (Although, more fortunately, this also means it doesn't force memory usage much larger than the textures themselves, either)
  7. Java. Thanks for the replies and I do appreciate the sentiment. I admit that I have a some recurring issues with potentially-unimportant optimizations, but I am particularly bothered in this case by the fact that the significant majority of the class's members would be unused in the general case. It's not a matter of fussing about trimming 10% off the top of something, but rather that 90+% percent of it would be 'waste'. A rough calculation suggests something between 100-200 bytes of overhead for rarely-used properties (depending on exactly how many of them I implement), and only about 16 bytes for the ones that everything needs all the time. Such an imbalance really strikes me as wasteful and sloppy, but several schemes I've considered for reducing the memory footprint (like encapsulating related groups of properties in other classes, and letting the Sprite maintain null references if it doesn't use that type of property) significantly complicate the logic and don't always save that much memory either, due to needing to store object references and per-object overhead. As for the target hardware, I'm aiming for at least 5 year old computers (and really, actually aiming older than that, but haven't been able to even find one older than that in person, to benchmark stuff against) And yes, I realize that there's probably no realistic way to end up with a memory footprint too large even for that, but I don't feel it's good practice to accept too much 'padding', if one can avoid it. I was just wondering if there were some conventional strategies for this sort of thing, or whether it really was a typical compromise to just throw every conceivable type of property or effect that requires specific tracking into the sprite class, and accept the wastage. This is probably more true than I'm comfortable internalizing, I admit...
  8. I'm currently coding a basic 2d rendering system intended to be used as the base for a tile-based strategy game I plan to make. The beginings of it are implemented, and there are notes for future sections. It's nothing fancy, but it handles render batching to minimize state changes, basic effects like rotation, scaling, frame animation, and allows most properties be animated using arbitrary animation curves. However, I've come to an unfortunate realization about the design of my sprite class: given that the intended project is a retro turn-based strategy game, I know in advance that the non-basic fields of the sprite class will be unused by 95% of the sprites or more (at any given time). Almost none of them will be scaled or rotated or colorized or have motion blur or even animated outside of brief periods when actions are performed. Otherwise, they are largely static. So, in the most straightforward implementation, every Sprite would have fields for scaling, rotation, colorization, and multiple other properties, when I KNOW that this will be wasted memory at least 95% of the time. What can I do about this? Any recommendations?
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!