Game design? Documentation? Best practices for using gameobjects etc

Hi guys

First of all i appologize for the title. To be honest after rereading the entire post there are so many subjects and questions i just didnt know how to phrase the title best for other people to find it usefull :expressionless:

Im writing this thread because i recently started developing a game in the unity engine. Ive got experience in developing normal windows software and asp.net applications in C#.

After having searched the internet for a few days ive noticed there are almost no articles, tutorials or forum posts about general software design in unity. I would really like to hear from someone with more experience than me how they handle the planning of their games.

Needless to say making games is not at all like making boring business software!

Do you make any kind of design documentation? Domain Model? Is it even possible to do with unity and all these gameobjects and the way it interacts with the unityengine?

My team and i are aspiring to create a Card driven tower defense game.

Its basicly about drawing cards, combining them into special towers and using them to defeat the enemies.

Each card can exist in 3 different “states”

  1. At first the card is located in a deck of many different tower types. Here it is never visible to the player he just knows he can draw cards from this deck by pressing a button.
  2. The player can then draw a card and place it in his hand (where it will be represented by a plane, cube, 3d model) and he will be able to interact with it there.
  3. When the player is happy with the tower and its stats he will be able to play it from his hand. The tower then turns into a 3d model of the tower pictured on the card. The tower must then contain all the stats that the specific tower had at the time the player places it on the board/map.

One of the questions that constantly pops up in my mind is how to i handle the cards. Should they be instantiated as GameObjects from the moment theyre loaded from the data source or would it be smarter to exclude the monobehavior untill the card actually needs to be represented visually?

Would it be ok to simple start by loading 200 Gameobjects with different card statistics into the game or should i instantiate whenever i need a card?

Any general comments on game design and best practices on any of the subjects that i might have touched with this post would be greatly appreciated.

The same goes for any specific examples or tutorials that could be usefull.

Hope you guys out there has some input on this subject!

Thanks Aron :face_with_spiral_eyes:

The best way of using unity is to do it how you prefer to do it and imagine it should be done, and only fix it if it’s a problem. It might turn out it’s never ever your bottleneck.

I respect that oppinion but what i am ultimately trying to do with this post is to get a good start on the project with some general guidelines that will prevent me from having to recreate the entire project because i find out i have done something horribly wrong with the basic structure of the game xD

Atleast just to hear peoples oppinions on how they do. Just like you just gave me yours :slight_smile:

The fundamental property of a gameobject is that it has a transform that exists in 3D space. So I would only use gameobjects for cards that are actually in play somewhere.

The exception is that I would usually use is to create an empty gameobject called “Manager” that has all my management objects in it. It has no rendered component so it is just invisible, but it gives your game logic a place to live and you can persist it between levels. I’m not really aware of how you could instantiate objects outside of gameobjects so that is what I use. There may be a better way, but I am not aware of it and this method works well enough.

You should keep all your game and card logic as just general C# classes. Don’t use anything from UnityEngine; this is all just your code. Say you create a vanilla CardStats class. Conceptually, this would be your data. Create a CardManager component that can be attached to your manager and manages all your card objects. And make a PlayerManager to keep track of players, and a DataManager to create an interface to your data back end, etc. They can reference each other or make a DataController class. Depending on the scale of your game and how you like setting things up.

Inherit from a MonoBehaviour to create a “Card” script that you can attach as a component that has a CardStats object inside it. The Card script is your interface between your data and the game (i.e. the view)–MonoBehaviours acting essentially as a view controller. It translates between the data and the game, and determines how you want to display it. For example, you create a prefab with a Card component and a 3d mesh of a playing card, and it knows how to look into the CardStats object to generate an offset in the texture atlas it should look to properly render itself. Then you can instantiate Cards as you need (or, more likely, initialize Cards out of an object pool to avoid runtime garbage collection).

Similarly, you have a Tower component that also has a CardStats object, and uses it to know how to build the tower and what it should look like. When you play a hand, you simply shift the CardStats objects from your Card objects to a set of Tower objects. Your CardStats class doesn’t (and really shouldn’t) know anything about any of this.

In my opinion, I think you want to separate out your logic and data as their own separate entities inside a management object. GameObjects are only for things that exist physically in the scene, and then you just add whatever functional components they need hooked up with the proper data objects so they know how to act. Until a card needs to be drawn on screen, it doesn’t need to be in a GameObject.

For example, you should just go to the Asset Store and check out all the Unity Technologies demo projects. They’ve got quite a few, and they should give you an idea of how they set things up.

i prefer this way. have some non-monobehavior classes storing the data and when you need it create some gameobjects to represent them. this goes well with a pooling system (which prevents constant instantiate/destroy). this also allows some kind of manager what handles the interaction of the user with many instances (what you probably require for your cardgame). on the other hand when you only have 200 cards you could also maintain them as gameobjects as the other method is probably overdo as you gain little and have some addtional work.

it would be “ok” in the sense that you could get it working. but as you asked by planning ahead i think you aim for “quality” code (reusability, maintainability). but the decision how much quality you need is yours alone. for a simple learning project you cannot make it “false”. for a production game with many planned subsequent titles you should think a bit harder.

the way unity works is quite different from “nomal” oop-programming. it takes a while and some experience to get the concepts. do some tutorials, search the forum for card games, look in the assetstore if there are packages which may help you.
on the other hand there is no “best practice” as people have different experience and thus come to different solutions for the same problems. i think in the end its better to use a methodology you are comfortable with instead of one “dictated” by others you have difficulties to understand.

when you use your project as learning project it will look quite different as when you do some learning with other projects/tutorials first and do your project then. and thats nothing what can be resolved by some forum posts. experience cannot be told/trained it can only be learned the hard way by doing stuff.
what helped me alot is just reading the forums. you get some hints, learn the api and there are interesting discussions sometimes. there is so much collected knowledge out there. noone is going to repreat it for you when you are “too lazy” to take what is there already. when you have some specific questions why things are handled that way you are welcome to ask. but my pov your post looks like one of the many “give me everything i need to save me the effort” threads. and those are not very welcome here.
when you doubt your structure create some prototypes which use different structures and compare them. there is no “one fits all” solution.

Thank you so much for your input TheShane. Very helpful to make up my mind about this

Thank you very much for your comments and insight. This was not intended as a “Im lazy pls tell me what to do thread” - Im not expecting people to tell me exactly what to do - and so far ive gotten good response in the direction that i was thinking. Simply reading peoples thoughts on how to approach design is very helpfull and i think its fair to ask for something like this even if you seem like a newbie trying to cut corners. Again - thank you for the input

Just to support AronChan, its hard for me to figure out the design for my game as well. I feel like Im used to the OOP, but it feels like Unity dictates Component-Oriented Programming approach, right? It`s not obvious what should be attached to what: Is an inventory item just a prefab with script attached or is it a model class with a reference to a prefab?

you can still use oop but it has not the importance in unity any more. actually it could be hindering you when you overdo it. read this for an insight especially the mentioning of the “blob anti-pattern” shows in my opinion the advantage/power of component based design over oop.

OK, good article. How does Unity cope with Data-Driven approach? Like tweaking the game balance? Is the team, not only programmers, use the editor and exposed variables, instead of files with parameters?

yes. thats the intended workflow. you expose all modifyable parameters as public or serializable variables in your class and set them in the editor. so the gamedesigners does not need to program or change files to change the behavior. with custom inspectors you can also ensure a certain range for a variable. that makes it very flexible. albeit unity is not perfect in this. for example 2 people changing the same scene can cause problems and often require a manual merge of the scene (only possible in text format). but there are tools in the asset store to handle this and improve the workflow.

this mainly depends on how you need it. as a general rule of thumb you should not atach scripts to the model itself. when you change it in 3d program your settings are lost. instead put them on an empty gameobject and put your model as child beneath it.

exiguous , thanks for the insight)