Author Topic: [Programming] Organizing Data  (Read 5644 times)

Offline keith.lamothe

  • Arcen Games Staff
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 19,505
Re: [Programming] Organizing Data
« Reply #15 on: July 26, 2013, 12:31:18 pm »
Just saw this.  I don't actually do events or event-listening ;)

Delegates, though, I do a lot of, but generally to write code that is easier to understand (by putting the logic that a button is going to fire or whatever with that button's definition, rather than some other part of the file) rather than harder to understand.  Though occasionally I do actually want to use functions as objects for variable logic rather than a switch statement.  But no callbacks, to my knowledge (edit: sorry, misuse of "callback", as that's all a delegate is, really).
« Last Edit: July 26, 2013, 02:42:47 pm by keith.lamothe »
Have ideas or bug reports for one of our games? Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: [Programming] Organizing Data
« Reply #16 on: July 26, 2013, 12:46:42 pm »
No-events-ever is not a bad way to do things.

Just that Flash pretty much requires them.

There's no "main loop" unless...
a) you use an Enter-Frame listener on your main class
b) you create a timer-based loop...which uses a TimerEvent every time the duration has occurred.

You don't get mouse pressed/unpressed info...unless you listen for a MouseEvent.  Same thing with the keyboard.  AS2 had a "is key down" function you could call, but that no longer exists in AS3 and you must use a KeyboardEvent listener.

But with regards to custom events (GameEvents) I use them very very sparingly and only when race conditions are irrelevant.

For instance right now I have an event listener that listens for an entity's health to change, when that event fires, the main game class creates a text field, adds it to the display list, places it above the entity's head, and fills it with the value of how much the health of that entity changed.  If there ever is a race condition here, it's not going to matter.  In this case, the health delta is calculated by the entity and passed as data with the event.

Otherwise I'd have to make the Attributes class (which is an object that stores and tracks things like health, experience, money, etc.) aware of the display list, which it has no business knowing.

Offline keith.lamothe

  • Arcen Games Staff
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 19,505
Re: [Programming] Organizing Data
« Reply #17 on: July 26, 2013, 02:49:22 pm »
Sure, for an engine that's designed for generalized use, and specifically misuse by code written by unknown 3rd parties, the engine basically can't give you "mainline" control of the program, for initiailzation, main-loop, termination, or anything else.  Your code has to jump to its tune.  Same here: In Unity all (with possibly a few exceptions, I don't remember) our logic executes either in OnUpdate (the per-frame event) or OnGUI.  And we've mostly excised the latter and hope to do so entirely.

But basically we just have a bit of code to handle the "handoff" of control from the engine to our simulation/whatever and then the vast majority of our code has no idea the engine is even there.  That's part of why it was possible to port AIW from our custom .NET/slimdx engine to Unity with relatively little effort.  So the fact that the engine is based on (and arguably, should be based on) an event system really doesn't impact how we organize our data, our logic, etc.
Have ideas or bug reports for one of our games? Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: [Programming] Organizing Data
« Reply #18 on: July 26, 2013, 02:55:59 pm »
Quote
So the fact that the engine is based on (and arguably, should be based on) an event system really doesn't impact how we organize our data, our logic, etc.

True.

The whole reason "event listeners" came up was just an offhand comment of "how do I know that X happened?"

Specifically I want an item to know that the player went from a positive health value to a negative health value, jump in, add a potion's worth of health, then let the death-check occur (potentially saving the player from dying).  Which isn't really relevant to "how do I lay out my data structures" just "I like this method, now how do I get the desired behavior to occur?"  Events (as programmatic triggers) don't really play into it, but rather events (as points on a timeline).

Offline keith.lamothe

  • Arcen Games Staff
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 19,505
Re: [Programming] Organizing Data
« Reply #19 on: July 26, 2013, 03:03:14 pm »
Yea, and that can be a bit tricky.  The straightforward way to get that logic is to make sure that changes to the health variable (during the simulation at least, construction and/or deserialization can and often should "bypass" this logic) ONLY occur in one specific part of the code.  Often this is accomplished by making the health variable itself private and using a getter and setter to allow any access/modification of it, then put your special "check for last-ditch health item usage" in the setter.  In fact I'm guessing that part of the thread I haven't read yet covers this in detail ;)

That has its downsides, in that for instance the "SetHealth" function in AIW's ForegroundObject class is... sub-optimally long.  Not so much in execution time (most of the branches are very rarely taken, compared to call count) but in reading comprehension.  Thankfully the #region thing in C# and auto-outline-collapsing in a decent IDE allows both for vertical collapsing of the space and a brief "what this does", which mostly mitigates the issue for us. 

Until we get a null exception report from a user, of course, since there's no way (that I'm aware of) to get a unity release build to give line numbers in a stack trace (no matter how much the .pdb/.mdb debug-symbols files are packaged in) and the development builds have a mandatory watermark... that one thing is one of my top 2 complaints about unity.  The other being the lack of ability to really profile it like you could a "real" CLR with ANTS or whatever.
Have ideas or bug reports for one of our games? Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: [Programming] Organizing Data
« Reply #20 on: July 26, 2013, 03:48:01 pm »
Yea, and that can be a bit tricky.  The straightforward way to get that logic is to make sure that changes to the health variable (during the simulation at least, construction and/or deserialization can and often should "bypass" this logic) ONLY occur in one specific part of the code.  Often this is accomplished by making the health variable itself private and using a getter and setter to allow any access/modification of it, then put your special "check for last-ditch health item usage" in the setter.  In fact I'm guessing that part of the thread I haven't read yet covers this in detail ;)

Nah, wasn't really discussed.

And in either case, that item isn't implemented yet.  Or rather, the item is, but not its functionality.

It and another item are on my "find replacements" list just because they're so weird.

The other allows the user to "save anywhere" but is of marginal use (because traveling back to town is cheap) and expensive computationally (now monster state needs to be saved!  Currently leaving a level deletes all monsters and when you come back it respawns the ones that weren't outright dead).

Offline keith.lamothe

  • Arcen Games Staff
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 19,505
Re: [Programming] Organizing Data
« Reply #21 on: July 26, 2013, 03:54:13 pm »
Yea, the need for mid-level saves can be a bit of a bear.  Depends on the game: sometimes granular persistence of each level is basically what makes or breaks the interest of the game.  But if it's not part of the design it's by far best to avoid.

You could implement the item as "warps you back to town instantly and saves your game" but that may not be the desired idea ;)

On serialization in general, it helps to have a very clear idea of the object "hierarchy" in terms of what "owns" what.  For instance, during the sim there might be 15 different references to a monster (in a list on the main "world" object, in a list on the level object, in a "currently targeting" reference on the player and/or other monsters, in the "currently standing on me" list on one or more tile objects, etc... but in serialization only _one_ of those should serialize the monster as a sub-entry, and the others (if their association with the monster needs to be retained across save/load) should simply serialize a unique identifier for the monster so post-deserialization code can recreate the association.

Anyway, once you're used to doing a lot of serialization it's really not a big deal to do mid-level saves if you need to; more a question of whether it's just borrowing trouble or actually a good thing for the game.
Have ideas or bug reports for one of our games? Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: [Programming] Organizing Data
« Reply #22 on: July 26, 2013, 04:07:39 pm »
Yea, the need for mid-level saves can be a bit of a bear.  Depends on the game: sometimes granular persistence of each level is basically what makes or breaks the interest of the game.  But if it's not part of the design it's by far best to avoid.

You could implement the item as "warps you back to town instantly and saves your game" but that may not be the desired idea ;)

That is a consumable item you can literally buy. :P  Another use will even warp you back down to where you were again.

Quote
On serialization in general, it helps to have a very clear idea of the object "hierarchy" in terms of what "owns" what.

Not serializing things.  I've more or less hardcoded saving the player's variables, then have a function for each level and item that saves out its variables (the base level definition handles 99% of all the levels without having to override it, because almost nothing unique about a level needs to be saved) and another function to load them back out again.