|
Actually, this isn't a case for unit tests, but a case for invariant checks. When you run in "development mode", activate some code that routinely (i.e. every tick, or alternatively every time you create/destroy/convert/whatever a unit) checks whether everything in the game is in the correct state. In this case, I mean you check whether unit.getTeam() and team.getUnits() are consistent. Then, when an error occurs, you'll know right away. Make sure this code is active when you're testing (interactive or through automated tests), and consider disabling it (for performance issues) when you're doing a release build. This practice is called (part of, actually) Design By Contract.
|
# ? Jan 19, 2011 10:14 |
|
|
# ? May 13, 2024 14:19 |
|
The invariant checks seem like a good idea. Orzo posted:Why are you coding the same pattern 4 times? What language are you using? C# with XNA. I outlined the four types of relationships in my first post: Unit-Team, City-Team, Unit-Tile, City-Tile
|
# ? Jan 19, 2011 14:29 |
|
HappyHippo posted:The invariant checks seem like a good idea. Couldn't Unit and City share a common base class? Seems like they have a lot of similarities...
|
# ? Jan 19, 2011 16:37 |
|
HappyHippo posted:The invariant checks seem like a good idea. Pfhreak posted:Couldn't Unit and City share a common base class? Seems like they have a lot of similarities...
|
# ? Jan 19, 2011 16:49 |
|
Orzo posted:No offense but that sounds like an awful idea, don't introduce base classes just because two things are similar. Well, at the very least, if they possess similar properties in the same context they should share an interface.
|
# ? Jan 19, 2011 16:54 |
|
Internet Janitor posted:Well, at the very least, if they possess similar properties in the same context they should share an interface. This is what my caffeine free brain was trying to say in the morning. I had meant to say abstract base class. Edit: Just noticed he said C#. Interface is fine for this. It seems like, and I don't understand the entire context of his game, there is a board with a number of pieces that sit on top of that board. Those pieces are sometimes units and sometimes cities. If both types of pieces have similar behavior and the same data... (ie, position, ownership, etc.) Although a case could also be made for building aggregates from various tokens that hold that information. Or a case could be made for getting it done and not worrying about the architecture too much because, gently caress, let's just finish a game already. Pfhreak fucked around with this message at 18:17 on Jan 19, 2011 |
# ? Jan 19, 2011 18:11 |
|
HappyHippo posted:Another solution would be to have every unit remember what team it's on This one. Yeah it's prone to bugs but if you get worried about introducing bugs you'll never get anything done. In my games I usually have a pointer in the unit to the team and a vector or list in the team that goes to the unit. These are also smart pointers so that if either entity goes away (the team loses or the unit dies) then the pointer starts to return NULL instead of invalid data. Bugs will crop up once in a while, that's what QA is for. wlievens mentioned a good method for keeping things bugless. noroomfortuna posted:Also, it seems weird to me to have teams bother to remember what units are on them - when do you need to do an action on an entire team? All the time. I'm working on a turn-based strategy game and I made special methods that help me iterate through every team member because i do it so much. The bots use it to decide on moves for each tank. At the beginning of every turn, each unit has a StartTurn() method that resets their powers or makes progress on whatever task they've been set to. The HUD uses it to see if every unit has been moved yet so the turn can end. If the team is defeated then every unit on that team dies. And so on. Keeping a per-team list is much faster than looping through every entity in the game and skipping those that don't belong to the desired team. Orzo posted:No offense but that sounds like an awful idea, don't introduce base classes just because two things are similar. Eh? So, if both cities and units both belong to teams, they shouldn't share a base class that makes team management code simpler?
|
# ? Jan 20, 2011 04:38 |
|
Vino posted:Eh? So, if both cities and units both belong to teams, they shouldn't share a base class that makes team management code simpler?
|
# ? Jan 20, 2011 04:48 |
|
I'd argue that difficult to maintain code would be that which requires keeping separate lists for different types of units, but I suppose that's best taken on a case by case basis. What would you qualify as "horrible" inheritance hierarchies? Those with multiple superclasses for any given subclass? Something else?
|
# ? Jan 20, 2011 08:59 |
|
I'd rather not introduce a base class for the cities/units. They are almost entirely distinct in terms of how the game treats them. Just about the only thing they share is that they are owned by teams and that they have locations on tiles. I tried to come up with a solution based on interfaces (one for things that "own" other things, and another for "ownable" things) but the result was a mess and it'll probably be easier to just go with the obvious solution along with the invariant checks.
|
# ? Jan 20, 2011 15:51 |
|
Vino posted:I'd argue that difficult to maintain code would be that which requires keeping separate lists for different types of units, but I suppose that's best taken on a case by case basis. By horrible inheritance hierarchies I meant ones that go up and up and up multiple levels. It makes poo poo hard to read and hard to refactor.
|
# ? Jan 20, 2011 18:11 |
|
Vino posted:I'd argue that difficult to maintain code would be that which requires keeping separate lists for different types of units, but I suppose that's best taken on a case by case basis. I'd like to add that we'd like to not have to keep all these different inter-relational lists/maps, but it just matters so much in terms of speed when doing frequent operations (sometimes per-frame even). A necessary evil given certain types of games.
|
# ? Jan 20, 2011 18:18 |
|
HappyHippo posted:I'd rather not introduce a base class for the cities/units. They are almost entirely distinct in terms of how the game treats them. Just about the only thing they share is that they are owned by teams and that they have locations on tiles. And selectable, and they maybe affect the player's visibility of the map in some similar way, and possibly have health/damage relationships, display on the HUD in similar ways, and okay I'm talking about my own game now. I see you guys point though.
|
# ? Jan 21, 2011 08:34 |
|
Vino posted:And selectable, and they maybe affect the player's visibility of the map in some similar way, and possibly have health/damage relationships, display on the HUD in similar ways, and okay I'm talking about my own game now. Those actually sound specifically like things I'd want to use an interface for. They're disparate entities that are used in many similar ways. That's pretty much the textbook case for an interface.
|
# ? Jan 21, 2011 17:27 |
|
It looks like http://www.garagegames.com/ is back with some deals on their engines. You can pick up any of their engines for $99 with source included. I have no experience with them and was wondering if some goons could weigh in on these engines. I am mostly interested in their 2d stuff. How does their 3d engine compare to Unity3d? Are they just cash grabbing to make a quick buck off these engines before they die out? In my time as a hobby programmer I have tinkered around with c++/sld or c#/xna for my projects. I mostly do 2d stuff that never really comes to anything because I get trapped in a cycle of messing with all the underlying architecture of the engine. Having a good 2d engine that is actively supported would be nice if I could just knock out some fun mockups and have them be usable on mac and pc.
|
# ? Jan 21, 2011 21:57 |
|
SlightlyMadman posted:Those actually sound specifically like things I'd want to use an interface for. They're disparate entities that are used in many similar ways. That's pretty much the textbook case for an interface. Except none of those things are true in my case.
|
# ? Jan 22, 2011 01:00 |
|
HappyHippo posted:Except none of those things are true in my case. Sorry I was mostly responding to Vino. Obviously do what's best for your situation.
|
# ? Jan 22, 2011 02:05 |
|
SlightlyMadman posted:Those actually sound specifically like things I'd want to use an interface for. They're disparate entities that are used in many similar ways. That's pretty much the textbook case for an interface. No. These are things you want components for.
|
# ? Jan 22, 2011 03:41 |
|
lynerd posted:It looks like http://www.garagegames.com/ is back with some deals on their engines. You can pick up any of their engines for $99 with source included. I have no experience with them and was wondering if some goons could weigh in on these engines. I am mostly interested in their 2d stuff. How does their 3d engine compare to Unity3d? Are they just cash grabbing to make a quick buck off these engines before they die out?
|
# ? Jan 22, 2011 04:20 |
|
SlightlyMadman posted:Those actually sound specifically like things I'd want to use an interface for. They're disparate entities that are used in many similar ways. That's pretty much the textbook case for an interface. That's a fair point, next time I'll have to rethink the design a bit more. Now that I think about it, it could probably have been done better this way. Thank you for the insight.
|
# ? Jan 22, 2011 12:04 |
|
I've been learning C# for a month or two now thanks to a recommendation in this thread. Slow but steady progress. I've got to the point where I'm seeking out code to read through and hack around with. I downloaded someone's implementation of Dope Wars in C#, which runs through the console. When I scanned through it, I understood it, and it looked it should all play out fairly predictably, but hilariously, far from working, the code is actually broken right at the beginning. I ran it in debug mode in Visual Studio and it loops around and around when asking the user for a menu option. I looked at the value of the variable where the keypress is being stored, and it's off - '53' instead of '5', for example. Couldn't figure out why it would do that. I tried changing how it was parsing it but that didn't have any effect. So I cheated and read the comments on that site quote:your key press routine is off. menu_choice=Console.Read().ToString(); returns the ascii value of the key pressed, so no valid key will ever be pressed. Plus you need to ignore the enter key (ascii 13). Ah. This is the specific section of code that seems to contain the error, to my (limited) understanding code:
(if anyone cares to look any further, the project code just needs converting to open in VS).
|
# ? Jan 22, 2011 13:18 |
|
This is some sample code of how I solved the problem of processing object interactions. Critiques or thoughts?code:
|
# ? Jan 22, 2011 15:44 |
|
Harmonica posted:I've been learning C# for a month or two now thanks to a recommendation in this thread. Slow but steady progress. I've got to the point where I'm seeking out code to read through and hack around with. Basically you need to subtract 48 from the values you are getting to get the numeric value.
|
# ? Jan 22, 2011 16:13 |
|
ShardPhoenix posted:You need to convert from the ASCII value to the numeric value you are looking for. See http://www.asciitable.com/ No, because int.Parse takes care of that. I would guess that you need to get rid of the newline character at the end of your input. Print out the value of int.Parse(menu_choice), and look at what it gives you. If it's "Error", the input is not a valid integer.
|
# ? Jan 22, 2011 18:46 |
|
Moof posted:No, because int.Parse takes care of that. I would guess that you need to get rid of the newline character at the end of your input. Print out the value of int.Parse(menu_choice), and look at what it gives you. If it's "Error", the input is not a valid integer. Actually, ShardPhoenix is right. Console.Read() returns an int with the ASCII value that gets converted to string and then back to int again, which changes nothing. Harmonica even mentioned getting 53 instead of 5. He needs to either subtract 48 or use a different method to read input, like Console.ReadLine(). Converting the ASCII to a char, then to a string, and finally parsing it to an int would also work I think.
|
# ? Jan 22, 2011 19:50 |
|
Cray posted:Actually, ShardPhoenix is right. Console.Read() returns an int with the ASCII value that gets converted to string and then back to int again, which changes nothing. Harmonica even mentioned getting 53 instead of 5. He needs to either subtract 48 or use a different method to read input, like Console.ReadLine(). Converting the ASCII to a char, then to a string, and finally parsing it to an int would also work I think. Oooooooh yes.
|
# ? Jan 22, 2011 19:54 |
|
PnP Bios posted:This is some sample code of how I solved the problem of processing object interactions. Critiques or thoughts? Also you don't need to call .Invoke on a delegate, just open the parenthesis. code:
|
# ? Jan 22, 2011 20:56 |
|
Cray posted:Actually, ShardPhoenix is right. Console.Read() returns an int with the ASCII value that gets converted to string and then back to int again, which changes nothing. Harmonica even mentioned getting 53 instead of 5. He needs to either subtract 48 or use a different method to read input, like Console.ReadLine(). Converting the ASCII to a char, then to a string, and finally parsing it to an int would also work I think. Even better solution would be using Console.ReadKey(), which reads only one key as input and returns more useful information.
|
# ? Jan 22, 2011 21:08 |
|
Orzo posted:Your code is fine. I don't know if you'll want this or not (it depends on your desired end design), but for your particular example I've made a few modifications to take advantage of generics. The main problem (it might not be a problem at all, if you don't need it!) with your code is that the callback delegate receives BaseObject, not the actual object defined in the interaction. Using generic interaction types, you can make your client code a little fancier. Note at the bottom how the interaction events take advantage of the specific types of the interaction (I've added dumb little properties to Red, Blue, and Green to demonstrate). You know... I knew this could be improved on with generics, I just didn't know how. Thanks!
|
# ? Jan 22, 2011 21:38 |
|
No problem, I have a couple more points. You'll notice that the value type of the 'reactions' dictionary is weaker (System.Object) now. This is because there's no way to strong type it with the two generic parameters, since they're variable within the dictionary. Also, if this is part of a larger project and not just a little toy to test code, you might want to consider turning the Interaction delegate into a full blown strategy. Presumably your interactions will become complex, requiring way more code than one would normally be comfortable shoving inside an inline delegate. So you'd end up with something like the interface 'IInteractionProcessor<T1, T2>' which has one method, Process(T1 obj1, T2 obj2). The nice part is you can still make one implementation that just wraps an Interaction delegate, so you can still use the shorthand when needed, but if you need more complex implementations you're free to use them without refactoring your entire code base.
|
# ? Jan 22, 2011 21:50 |
|
What's your actual use case for this interaction system? When it comes to games I'm very wary of writing anything generic especially as a first pass. What are the chances that you're making yourself a hammer before you've realised that you need to deal with screws?
|
# ? Jan 22, 2011 22:16 |
|
Bizarro Buddha posted:What's your actual use case for this interaction system? When it comes to games I'm very wary of writing anything generic especially as a first pass. What are the chances that you're making yourself a hammer before you've realised that you need to deal with screws? I'm working on a game engine. (insert rolly eyes here...) but I've already got a few demos working. This system in my case is specifically for object collisions. such as player-bullet, player-switch, etc. The idea being it can be extended to more than just first person shooters. I would say that it's over 90% complete, and am working to implement a game with it. Currently I have about half a dozen sandboxes testing various features.
|
# ? Jan 22, 2011 23:07 |
|
People will tell you to write games, not engines. It's an annoying mantra parroted all over the place by people that probably wrote an engine at some time and failed. Do your own thing, writing an engine is a great learning experience which may or may not end up in a successful game.
|
# ? Jan 22, 2011 23:28 |
|
Orzo posted:People will tell you to write games, not engines. It's an annoying mantra parroted all over the place by people that probably wrote an engine at some time and failed. Do your own thing, writing an engine is a great learning experience which may or may not end up in a successful game. I'm usually one of those people, but I have a good reason for writing this one. I'm going for a specific look, and I'm keeping things ridiculously simple.
|
# ? Jan 22, 2011 23:38 |
|
PnP Bios posted:I'm working on a game engine. (insert rolly eyes here...) but I've already got a few demos working. This system in my case is specifically for object collisions. such as player-bullet, player-switch, etc. The idea being it can be extended to more than just first person shooters. I would say that it's over 90% complete, and am working to implement a game with it. Currently I have about half a dozen sandboxes testing various features. Orzo posted:People will tell you to write games, not engines. It's an annoying mantra parroted all over the place by people that probably wrote an engine at some time and failed. Do your own thing, writing an engine is a great learning experience which may or may not end up in a successful game.
|
# ? Jan 22, 2011 23:57 |
|
Bizarro Buddha posted:Sounds reasonable for triggers like switches, though for collisions like bullet-player you'd usually want more information like point of intersection, normal, and so on, which makes your system less generic. Bizarro Buddha posted:These people are right. An engine is something that grows out of carrying code over between projects. If you set out to write "an engine" with no game to keep the feature set on track and constantly tested for usefulness, you'll end up with a huge set of systems that are of absolutely no use to you in practice. You should listen to people that tried things and failed, and think about the reasons, rather than calling it an annoying mantra. This isn't a from the ground up engine design. This is the refinement of a series of prototypes. This is the 7th iteration, which I'm going to turn into a full blown game instead of a fancy physics test.
|
# ? Jan 23, 2011 00:09 |
|
Bizarro Buddha posted:These people are right. An engine is something that grows out of carrying code over between projects. If you set out to write "an engine" with no game to keep the feature set on track and constantly tested for usefulness, you'll end up with a huge set of systems that are of absolutely no use to you in practice. You should listen to people that tried things and failed, and think about the reasons, rather than calling it an annoying mantra. I think we're talking about slightly different things. I agree you shouldn't just write an engine without developing a game concurrently, for the most part. You'd be surprised how many people, though, will criticize even the slightest effort to abstract ideas into an engine (whether it be a different assembly/module, or whatever). The entire thing also depends highly on the goals of the programmer, too. There is personal value gained by writing an engine just for the hell of it. If your goal is to learn a language, set of technologies, improve your code, or a handful of other aims, writing an engine can be a rewarding experience. If your goal is to get a game out, you should obviously be developing a game concurrently with the engine. The mantra is annoying (to me) because it makes a ridiculously bold assumption about the aims of the developer. A more reasonable saying would be 'write your game and engine together', because it at least applies only to people who aim to make a game.
|
# ? Jan 23, 2011 00:12 |
|
PnP Bios posted:Position and velocity are components of the game objects. I have a different pass for the level geometry. PnP Bios posted:This isn't a from the ground up engine design. This is the refinement of a series of prototypes. This is the 7th iteration, which I'm going to turn into a full blown game instead of a fancy physics test. Yeah, this is exactly what I'm talking about. You write the code you need for your prototype, and then you carry the good stuff over to the next one.
|
# ? Jan 23, 2011 00:17 |
|
Bizarro Buddha posted:Slightly nitpicky but position and velocity doesn't give you intersection point and normal without doing work that you probably would already have done in your collision detection, so it doesn't make sense to be forced to redo that work in the handler. I think you under-estimate how simple my engine is. Right now I'm only doing cylinder-cylinder detection.
|
# ? Jan 23, 2011 00:27 |
|
|
# ? May 13, 2024 14:19 |
|
I wonder how many times this same discussion about striking a balance between doing stuff well and actually getting games done has happened in this thread, it must be once every 3 or 4 pages by now.
|
# ? Jan 23, 2011 00:39 |