[C#] Wink2D Engine

Started by winkio, November 09, 2010, 02:58:34 pm

Previous topic - Next topic

winkio

November 09, 2010, 02:58:34 pm Last Edit: December 07, 2010, 03:54:37 am by winkio
So the game dev club at my university is thinking about making an engine in C#.  I was specifically tasked with thinking about how to make a parent class for all game objects, such as characters, enemies, particles, tiles, etc.  The goal is to provide easy access to create complex game objects through a sort of simplified scripting language.  This is my initial idea:

class GameObject has 3 main pieces of information:

1.  string Name - this is mostly for organizational purposes in whatever editor eventually gets made, and it has no influence on the actual game.
2.  Dictionary<string, object> Properties - this will allow the user to create extra variables and properties through the editor that are not hardcoded into the classes.
3.  Dictionary<string, List<string>> Commands - each List<string> value is a list of pseudo-script commands that can be interpreted by the game engine.  There can be many such lists run at different times, such as every frame, on collision, on interaction with a certain type of event, etc.  The condition on which the list is to be run could be represented by the first command in that list.

There are also 3 methods to be implemented:

1.  Update - needed to have a dynamic object.  This will additionally check each list of commands to see if it needs to be processed.
2.  Interact(GameObject o) - interacts with another game object
3.  Process(string command) - processes a command.  Someone will have to build a lot of functionality into this, as it is what interprets the pseudo-script commands.



So, any thoughts? Something obvious (or not so obvious) I'm missing?  Rampant memory leak or speed reduction?

Blizzard

November 09, 2010, 03:30:15 pm #1 Last Edit: November 09, 2010, 03:35:07 pm by Blizzard
Well, there are loads of things that should be considered. If you don't really care for memory, you can leave the string Name attributes. I prefer having a name for all my objects as well, but it can eat away quite some memory if you have a million objects and each has a name of average length of 20 characters (which results in additional 20 MB of memory).

If you want a really good system that uses commands, I suggest that you create appropriate classes for it. Just using strings is alright for a smaller engine, but if you plan it to be extendable, I'd definitely go with additional classes such as Event, Command, etc.

The Properties thing is a good idea for a generic class, but I don't think you need it that much. Sure, it could make things easier and more dynamic but also more prone to bugs and logical errors (such as literally typing mistakes in the strings used as keys). You could use it for a data model or something like that.

As for the methods, not every object really needs an update method. I'll explain this a bit later. Same with Interact. Process sounds like a good idea, but I'm not sure exactly how you want this to work.


The last engine I have worked on is separated into 5 main parts. I have listed 6 parts here, because I never implemented a proper Menu Model.

Part 1: Static Data Model

The Static Data Model is pretty much what one could call a database. If you know RMXP's scripts, then the static model would be pretty much the data classes in the RPG module. Also, this model doesn't need any update method. It's simply unnecessary. A static model should have a base class from which all other classes are derived.

Part 2: Dynamic Data Model

The Dynamic Data Model represents the objects in the game. Those objects should reference Static Data objects which define their basic template data. Those two models will probably have a very similar inheritance structure. These objects should be able to provide an interface to the outside, but they shouldn't be able to actually do much on their own. This model would obviously have to be updated every frame.

Part 3: View Model

These objects should be used to display the Dynamic Data Model. A GUI library would be the closest thing to a View Model. RMXP's sprites would be kind of close to this one, but IMO they are bloated. This is another model that would have to be updated every frame.

Part 4: Menu Model

This one is obvious. Menu objects display information and data and allow the user to interact and change that information and data. From my personal experience to come up with a good Menu Model is difficult. To come up with a good and generic Menu Model is extremely difficult. This is a model that might not require updates all the time, but an update method might still be a good idea.

Part 5: Controller Model

Controllers define and control how Dynamic Data objects behave and interact with each other. They should also handle user interactions. The scenes from RMXP are an alright example. The Sprite classes in RMXP are also Controllers, but they are kind of messed up. IMO a general Controller Model should be separated from a display Controller Model. Another object model that needs to be updated.

Part 6: System Model

There are usually many small classes or general purpose classes that also need to be implemented. I like to call them System objects. Good examples of System classes would be:
Save Game Manager
Game Profile Manager
Scene/Game-Logic Mode Manager
Menu Manager
Map Position (a "Vector2" with x, y or "Vector3" with x, y, z could be used for this, but I had my reasons for a separate class, it's a long story)
Game Data (the object containing all the game data)
Generic Condition
Generic Condition Set
AI Module
Depending on what kind of object it is and what it does, it might or might not required an update method.


In the end, you should adapt your model to suit your needs rather than making an all-purpose engine. Cut down on properties and generic concepts if you don't need them or don't really see yourself actually using them in your engine. They can be just a waste of your time which you could have used to implement features that matter.
To me personally a similar structure was very useful as I was able to reuse loads of it for a new project. I've been working 8 working days on it for now and it's about 70% done. The full game will probably be done within 15 days of work. Sure, it's a quite simple game, but because I was able to define, separate and implement many useful concepts in MB, I already had loads of stuff already finished and ready to go so that this new game will take a ridiculously short amount of time to make. :) If I didn't have all of that, I would have at least required another 15 days and the end result wouldn't have been as nice and systematical as this will be.

EDIT: BTW, I named my namespaces Database, GameObject, Scene and System. I then used a class Base in the first three to define a base object with all the common properties that are required for every object of that model. While Database::Base and GameObject::Base are quite simple, Scene::Base turned out actually quite complex yet not bloated. I was playing with the thought to rename the namespaces to Data and Game just to be able to write shorter, but namespace Game would probably mess with System::Game so I left it all as it was. Just throwing that thought out there. Maybe you can make something out of it.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

:D Good stuff Blizz.  We have already roughly divided the engine into different parts.  Our divisions were:


  • Base - low-level generic classes (such as game_object)

  • Graphics - self explanatory

  • MathPlus - was going to be named Math, but didn't want to confuse it with system.Math.  Lots of geometry related stuff and higher level math

  • Multiplayer - methods for split-screen, networked play, etc.

  • Physics - methods for creating simple physics, as well as a physics engine

  • Pipeline - used to read and write the file formats for things such as levels, particle effects, etc.

  • TileMap - framework for creating maps containing 2D tiles

  • Screens - used for handling different game screens and menus

  • System - extra stuff, such as input, save data, etc.



As you can see, we divided up based on the different features of a game.  There's some mixing of static and dynamic data, as well as controllers within each division.  Is this method of organization inferior to yours, or would it still work?

And yeah, we want to have an engine that can be used for all sorts of games (fighting, platformer, puzzle, etc.), yet have a lot of genre-specific stuff built in, so that it won't take as long to create a game of a specific type, and we can reuse a lot of code.  So it's supposed to be something like a 10-in-1 engine.  Because once it's finished, the club (of about 30 people) wants to pursue 3 or more projects simultaneously.

Now, back to the analysis of the GameObject class.  How we conceived it was equivalent to the base Dynamic Data Model.  That is why it has update and interact built in.  Other people are working on our equivalents of the other models.  We are going to recombine ideas on Sunday.

Process will function like the Interpreter in RMXP - it takes a command, and then executes it.  Now that I think about it, it will probably need a helper method to take the whole command list at once, because of conditionals and such.  Due to inheritance, it also allows new objects to have new commands (for example, give a Chicken object the Egg command).  It was my idea of a simplification for non-programmers, where in the editor, they could click on an object, and a list of possible commands specific to that object would come up, and then they could just choose one, fill out a form, and be done.  For the implementation in the base class, it would just have simple things like (Add/Remove Property, Set Property, Erase Object, etc.).

Blizzard

November 10, 2010, 02:45:41 am #3 Last Edit: November 10, 2010, 02:47:19 am by Blizzard
I don't think it's inferior at all. It's just different in some aspects, but it's also similar in others. In fact in the last engine I worked on had the 5 parts I mentioned where I coded 4 of them. The GUI part is a library that we made in Cateia (I am currently refactoring the code massively). We also made a high level types library, a geometry types library, a rendering interface library (that works with both DirectX and OpenGL, yay), a font rendering library and an audio library (we released all of them as Open Source libraries). Since we're working in C++, some of those libraries (such as HL-Types) are very useful to make code shorter, more readable and more organized. :) So we have actually more than just the 6 parts, but the 6 parts are a general outline just for the game logic. The rendering engine is a separate part for itself. Audio could be a part in itself as well or it could be included in the System part. It pretty much depends on how you organize things.

As I said, I think the model is quite good. It's good that you have modularized specific parts of the engine. This will allow you to quickly reorganize the models and refactor the code if you find flaws with the current model and come up with a better one. :)

I hope you can learn a lot from working on that engine. :)
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

November 14, 2010, 07:23:57 pm #4 Last Edit: November 21, 2010, 02:56:48 am by winkio
Well, just had an interesting meeting today.  I was one of the two people that actually put some effort into their part of the engine (the other being the club president).  And the club is getting restructured for next semester, and so focus has switched to that.  End result: the engine is no longer in the club picture, but I'm picking it up as a personal project.

So anyway, I've started making the GUI for the engine, and I'll probably be making posts about that sometime soon.

EDIT:  Well, this is turning out to be really hard, but really fun.  I've made a custom scrolling tabbed document system, sidepanels that display different information and give the user different tools and functions based on what type of file they are editing, and a dynamic layout scheme that organizes all program elements whenever the window is resized, allowing the GUI to run at any resolution.

EDIT:  And sure enough, it was easy to get XNA to render inside the application.  At this rate, I might finish a prototype over winter break :D

Blizzard

Sounds great, winkio! :D

I know what you mean by it being hard. xD Especially when you're doing something like this the first time. New possible problems keep popping into your mind and you have to reconsider the design over and over several times. xD
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio


G_G

Well I think its a tad bit obvious you or whomevers computer that is, name is ryan. Nuff said.

Nice job btw.

ForeverZer0

Quote from: game_guy on November 25, 2010, 08:10:11 pm
Well I think its a tad bit obvious you or whomevers computer that is, name is ryan. Nuff said.

Nice job btw.


You mean his real name isn't "winkio"!? I'm shocked!  8-O
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

winkio

lol, my email address is my last name followed by my first name.  And that's in the Blizz-ABS manual.  So... yeah, I do have a name, and I'm not afraid of people knowing it.

G_G

neither am I. I was just pointing the obvious out :P

ForeverZer0

To get back on subject, this is looking good. Are you releasing it when done?
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

winkio

Ah, but of course!  Why would I put so much work into something, and then not show off the finished product?

But, in terms of being done, it's going to be a while.

Blizzard

HAHA! FILENAME IS NOT! AND YOUR NAME IS RYAN! Ah, wait, you don't mind people knowing your real name. ._.

You should rename to engine to Win2D, though. <3
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

winkio

November 26, 2010, 11:42:28 am #14 Last Edit: December 07, 2010, 03:54:52 am by winkio
Wink is sexier.  And since it's built on top of XNA and .NET, I don't want any additional affiliation with Microsoft and Windows.

EDIT: Okay, I think I'm finally nearing the end of my 5 hour long battle with XNA rendering.  See, XNA doesn't have any built in way to draw a 2D line, or a 2D rectangle, or a 2D triangle, in terms of pixels, like we are used to in the 2D game community.  It's built for 2D sprites, and 3D rendering, so the only way to draw 2D lines, or rectangles, or triangles is to render them in a 3D environment.  Of course, 3D environments are a lot more complex, so I had to get it to draw with the right view and projection matrices, and use rendering effects.  These rendering effects depend on the size of the render area, etc.

Anyways, I can finally draw anything from polygons to ellipses without it lagging like hell.  Now, it's time to put them to use.  Custom Geometries time!

EDIT 2:  The result of a night spent on gridding: Custom tileset grids!
Spoiler: ShowHide

rectangular


isometric


elevated isometric


horizontal hexagonal


diagonal hexagonal



Blizzard

Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Ryex

as much as I think that costume grids are cool I doubt that you made this feature just for that. what purpose dose this serve in the long run? what incredible feature do you have laying in wait?
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

winkio

making games from different viewpoints.  It doesn't show from the screenshots, but you can define the size of each shape, allowing you to make tiles that actually correspond to doodads or terrain.

Examples of different viewpoints:
Spoiler: ShowHide



ForeverZer0

I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Aqua

Your isometric doesn't seem right to me... o-o
But the rest...
Mmmmmm :3