• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

dsm1891

Members
  • Content count

    343
  • Joined

  • Last visited

Community Reputation

2746 Excellent

About dsm1891

  • Rank
    Crossbones+

Personal Information

  • Location
    UK
  1. Agreed. The designer isn't sure, and is hedging. When I've been unsure like that, I've said that the feature should be made flexible so it can be easily changed. I've also worked with a designer who would poll the team before designing a feature. dsm, you say you'd rather be told. Would you like to be told to do it one way, then be told to change it later? I don't think you'd like that. But a designer can't be certain all the time, so why don't you just discuss with the designer - sounds like he/she/they is laboring in a vacuum.   Well, in previous projects where there was no designer per se I was more than capable and enjoyed filling out a mechanic of what felt good. But atleast on this project numerous times I have... been made aware of that is what the designer did not intend (when I have fledged out a mechanic with what I thought should happen).    So now it seems I am in a place where the designer cant/wont make concrete decisions and if I fill out ambiguities I will be told that that is not what they had in mind.   Of course being told what to do, and potentially having to redo it would be annoying. But I think that would only be the case if the iterations are frequent.   as previously said, discussions lead no where. I will be provided with a vague task, I ask about the task, the answers are equally vague. Trying to promt some decision I give multiple options, in which the designer will say "any of those options". Then the next day I will be told something totally differently  (without the designer seeing the implementation)
  2. No producer (yet, may hopefully change)   These ARE first pass, so it is, in a way prototyping. However, I would much rather be told what the first implementation should do.   For instance I Just asked the designer, "how should this be implemented the options are , A,B or C" to which the reply I got was "Yes, any of them". It seems the designer is afraid of commitment. Previously I have communicated verbally to him, which turned out to be a disaster.   I asked about X feature which I was to implement and he described the feature with some ambiguity. I thought fine, I can just do the obvious path. For example, I was to implement the character throwing a ball. It seems obvious to me, that when the ball is thrown, it is thrown with some force and is effected by gravity, has some sort of friction and restoration. After implementing it, I was told it was "just wrong" and that it would "obviously" travel in a straight line, not effected by gravity.    Yesterday I questioned him (again verbally) about something else, and resolved the ambiguities. But today he when questioned about something else he contradicted himself.     I am fine with things changing, but changing your idea of how something works day by day is frustrating. My idea how it should be is: Design it one way, play test, if it works great if not change it.   After the first instance of the ambiguities and my restricted freedoms (obviously the designer and I, don't share common ideas) I have stopped querying him face to face, instead I use the task manager comment system. So atleast I can refer to things he has said in the past on 'why I made it which ever way'     And before anyone asks we don't have a GDD *(or atleast one I can view)   and yes this is scrum, kinda, not really though :/
  3. Hello Designers   I come to you with a question. I am currently working with a designer whose writing style is, quite frankly, annoying to me. I am given a task to do X, but the description of X is full of indeterminable words.   "maybe it could, possibly, this pass, do THIS sort of thing, for now" (literal quote)   Designers I have worked with previously have never used this language, if something needs doing it was always definite   "It should be done like this"   I had no problem with this, if it needs to change in the future fine. Everything read clear cut. However using  indeterminable words make it sounds like I should keep the Thing I am developing open, as the designer thinks it will likely change in the future, and it makes me question how it should work.   Is this normal, or am I just complaining for no reason :)
  4. Welcome,   I think I need help. When ever I code a feature/system/helper/tool/whatever for a game, it has to be generic. I feel like I am addicted to making things as generic as possible, even when such systems don't need to be generic. Sure having generic systems can be great, but when ever I have to create a specific system, I still can get out of the mind set of 'how can this thing be more generic', and frankly things take longer than the should because of this.   So let me tell you where it all began. My first project in the industry was made using an inhouse engine with no editor. We tried to make thing as generic as possible so they would 'just work'. no faffing about. We used other editors, such as Tiled or someother software, to create data assets which would be loaded in to game, and 'just work'.   I was in charge of implementing enemies, particles, projectiles and such (which all came from one art package). Looking back on the project I love how it all 'just worked', The artist would create a character, I would go in *do some magic* export. Run the game, and that character (with simple AI) would be working as in tended. The whole thing was so independent of code you could have a character fire a gun, when the bullet exploded it could spawn a character, which then would explode spawn particles, damage surrounding,x ,y z - no code required.   It was great.   However, now I am working with unity, that has an editor. Things don't need to be as automatic as the previous project. its perfectly acceptable and easy to enter values. Because its easy to attach components to game objects, specific components are often a way to go. The existing code base when I joined the project was alien to be, because often it was very specific. Even now when I have to create a new system / re-write an old one, I write it generically. But it is Bottle necked by specific systems, and im left with a choice, make my system less generic or Change another system (which would spiral out of control!).   I think I need to learn how to know when to drop the Generic implementation of a system in favour for a more Specific implementation.   Any advice?   TL;DR: I always try and create generic systems in game, as a result things take longer than if it was a Specific implementation. How do you decide if something should be generic or specific.
  5. what was Yoshi talking to you about
  6. Unity Data Entry So, unity has a problem. Well, ok lots of problems, but I want to talk about a specific one. Data entry and how things can quickly get out of hand. For those who are unaware, unity allows you to edit serialize data through the editor using an 'inspector window'. My script has 3 variables that can be edited with types enum, int and float. (unity offers many other data types which can be edited through the inspector). Entering data through the inspector is fine for simple objects/scripts. However, once a object/scripts becomes more complicated the default data entry becomes a burden. Specifically when you have a variable which will determine if another variable is used or not. A good example of this is you may have a projectile, this projectile could behave in different ways. It could be a homing projectile, it could be a bullet, it could be anything. If the projectile is homing, it will use additional parameters to a standard projectile, if it is a bullet it would use different parameters again. The solution to this problem, as stated a lot of places on the internet is to create a custom drawer for the (projectile) script. However, in practice this is impractical. Scripts where I needed the above behaviour required writing 200 lines, just so I could show/hide some variables in the inspector! furthermore this 'solution' just isn't scalable, as you would have to write custom draw code for each script!. My solution to this involves using attributes to define when a variable is shown or not (and to handle the drawing) (in real time!) Which changes the above image to: So, What do we need to do? Create a generic attribute which any variable can use Use reflection to get another variable Check to see if that variable is of a particular value The most basic condition (to decide if one variable should be shown or not) is a Boolean.if Varible A is True Show Varible Belse Don't show Varible B First we have to declare our fields, this is pretty standard, however on variable B we will have to declare it with our attribute (conditional)public bool a;[Conditional("a", true)]public int b; as you can see, the attribute takes in two parameters; "a" and True. The first parameter is the name of the parameter we want to check. The second parameter is the value the first parameter needs to be to make variable b show. These are both stored with in the Attribute. We need to create a drawer, which will draw the variable in editor, for our attribute. We do this by doing:[CustomPropertyDrawer(typeof(ConditionalAttribute))]public class ConditionalDrawer : PropertyDrawer{ public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { .... }} The OnGUI method will handle drawing the variable in editor. As you can see, it has a SerializedProperty parameter, this is our variable "b". We need to do some reflection magic on that parameter to get variable "a" and check it's value. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { ConditionalAttribute conAtr = attribute as ConditionalAttribute; string path = GetPath(property); string conditionname = path + conAtr.ConditionVaribleName; ConditionalProperty = property.serializedObject.FindProperty(conditionname);} private string GetPath(SerializedProperty property) { string path = property.propertyPath; int index = path.LastIndexOf("."); return path.Substring(0, index + 1); } This code gets the condition variable ("bool a") and stores it in ConditionalProperty. The GetPath Method is needed as the variables could be nested in an object. ? ? Next we need to check the value of ConditionalProperty, against the value we passed (and stored) into the attribute. if (ConditionalProperty.propertyType == SerializedPropertyType.Boolean) { conAtr.ShouldShow = ConditionalProperty.boolValue == conAtr.CheckValue; } as the same instance of the drawer is used to draw all the variables with our attribute, we can not store anything with in the drawer. we have to store everything in the attribute. Next, still within the OnGUI method we need to draw (or not draw) the variable ("int b").if (conAtr.ShouldBeShown) EditorGUI.PropertyField(position, property, label, false); We also need to alter the height of the variable being drawn otherwise there will be a blank space. Luckily we can just do: public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { ConditionalAttribute conAtr= attribute as ConditionalAttribute; if (!conAtr.ShouldBeShown) return 0.0f; return EditorGUI.GetPropertyHeight(property, label, true); } within the drawer class. Great!! we now have a variable which is shown/not shown depending on another Boolean variable. But what if we don't want to use a Boolean, what if we want to make it dependant on another type, what if it has to be greater than X or less than X. What if we want it conditional to multiple things. Don't fear, I have thought of that! I have another constructor in the attribute:public enum OperatorEnum { Equals, NotEqualTo, GreaterThan, LessThan, EqualsOrGreaterThan, EqualsOrLessThan } public enum LogicEnum { AND, OR } //LHS, is the varible name to check which are got through reflection //Opperator, is the operator to use for the check //RHS, is the value to check against //BetweenElements, and/or to use between the last element and this element public ConditionalAttribute(string[] LHS, int[] Operator, object[] RHS, int[] BetweenElements) { int maxsize = LHS.Length; m_LHSVaribleNames = new string[maxsize]; m_Operator = new OperatorEnum[maxsize]; m_RHSValues = new object[maxsize]; m_BetweenElementsLogic = new LogicEnum[maxsize - 1]; m_LHSVaribleNames = LHS; for (int i = 0; i < maxsize; i++) { if (i < Operator.Length) { m_Operator = (OperatorEnum)Operator; } else m_Operator = (int)OperatorEnum.Equals;//Set it to == if no value was given } for (int i = 0; i < maxsize; i++) { if (i < RHS.Length) { m_RHSValues = RHS; } else m_RHSValues = RHS[RHS.Length - 1];//Set it to the last value if no value was given } for (int i = 0; i < maxsize - 1; i++) { if (i < BetweenElements.Length) { m_BetweenElementsLogic = (LogicEnum)BetweenElements; } else m_BetweenElementsLogic = LogicEnum.AND;//Set it to && if no value was given } } unfortunately, there are only certain types which can be passed into attributes. I would have liked to do all this using a lambda to decide all this, but alas that was not possible so I had to parse the values to make the correct statement. Also, enum values can not be passed through so they need to be cast to an int. So now if we want a new variable ("c") to be shown when:if a == true && b > 5 showelse don't show the declaration would look like: public bool a; [Conditional("a", true)] public int b; [Conditional(new string[] { "a","b"}, new int[] { (int)ConditionalAttribute.OperatorEnum.Equals, (int)ConditionalAttribute.OperatorEnum.GreaterThan }, new object[] { true, 5}, new int[] { (int)ConditionalAttribute.LogicEnum.AND} )] public float c; yikes that's a big constructor :( One last thing was that because I don't know the type of the variable who's name is passed in (the condition variable) - I only know the type of the variable being drawn, I had to use(IComparable)LHS).CompareTo(RHS) == 0 for the check to know if the variable should be shown or not. Using this attribute allows the data entry for unity to be much easier, as now you can edit fields that are relative to the options you have already chosen! You can now write, simple/complex statements and control the visibility of variables in the editor without the need of creating custom drawer's for each script. I am really happy with how this has turned out, it is really flexible and really generic. Hopefully someone else will find it as useful as I do :) Until next time, dsm full code:using UnityEngine;using System.Collections;using UnityEditor;using System;public class ConditionalAttribute : PropertyAttribute{ public enum OperatorEnum { Equals, NotEqualTo, GreaterThan, LessThan, EqualsOrGreaterThan, EqualsOrLessThan } public enum LogicEnum { AND, OR } protected string[] m_LHSVaribleNames; protected OperatorEnum[] m_Operator; protected object[] m_RHSValues; protected LogicEnum[] m_BetweenElementsLogic; protected bool m_ShouldBeShown = true; public bool ShouldBeShown { get { return m_ShouldBeShown; } set { m_ShouldBeShown = value; } } public string[] LHSVaribleNames { get { return m_LHSVaribleNames; } } public OperatorEnum[] Operator { get { return m_Operator; } } public object[] RHSValues { get { return m_RHSValues; } } public LogicEnum[] BetweenElementsLogic { get { return m_BetweenElementsLogic; } } //LHS, is the varible name to check which are got through reflection //Opperator, is the operator to use for the check //RHS, is the value to check against //BetweenElements, and/or to use between the last element and this element public ConditionalAttribute(string[] LHS, int[] Operator, object[] RHS, int[] BetweenElements) { int maxsize = LHS.Length; m_LHSVaribleNames = new string[maxsize]; m_Operator = new OperatorEnum[maxsize]; m_RHSValues = new object[maxsize]; m_BetweenElementsLogic = new LogicEnum[maxsize - 1]; m_LHSVaribleNames = LHS; for (int i = 0; i < maxsize; i++) { if (i < Operator.Length) { m_Operator = (OperatorEnum)Operator; } else m_Operator = (int)OperatorEnum.Equals;//Set it to == if no value was given } for (int i = 0; i < maxsize; i++) { if (i < RHS.Length) { m_RHSValues = RHS; } else m_RHSValues = RHS[RHS.Length - 1];//Set it to the last value if no value was given } for (int i = 0; i < maxsize - 1; i++) { if (i < BetweenElements.Length) { m_BetweenElementsLogic = (LogicEnum)BetweenElements; } else m_BetweenElementsLogic = LogicEnum.AND;//Set it to && if no value was given } } public ConditionalAttribute(string LHSVaribleName, object RHSValue) { m_LHSVaribleNames = new string[] { LHSVaribleName }; m_RHSValues = new object[] { RHSValue }; m_Operator = new OperatorEnum[] { OperatorEnum.Equals }; } public ConditionalAttribute() { }}///////Conditional//Decides if a varible should be shown in the inspector depending on another (boolean) varible[CustomPropertyDrawer(typeof(ConditionalAttribute))]public class ConditionalDrawer : PropertyDrawer{ public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { if (!bute.ShouldBeShown) return 0.0f; return EditorGUI.GetPropertyHeight(property, label, true); } SerializedProperty ConditionalProperty; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { bute.ShouldBeShown = ShouldShow(property); if (bute.ShouldBeShown) EditorGUI.PropertyField(position, property, label, false); } private string GetPath(SerializedProperty property) { string path = property.propertyPath; int index = path.LastIndexOf("."); return path.Substring(0, index + 1); } protected virtual ConditionalAttribute bute { get { return (ConditionalAttribute)attribute; } } protected bool ShouldShow(SerializedProperty property) { string path = GetPath(property); bool previous = false; for (int i = 0; i < bute.LHSVaribleNames.Length; i++) { string conditionname = path + bute.LHSVaribleNames; ConditionalProperty = property.serializedObject.FindProperty(conditionname); bool test = false; object lhsValue; if (ConditionalProperty.propertyType == SerializedPropertyType.Integer) { lhsValue = ConditionalProperty.intValue; } else if (ConditionalProperty.propertyType == SerializedPropertyType.Float) { lhsValue = ConditionalProperty.floatValue; } else if (ConditionalProperty.propertyType == SerializedPropertyType.Boolean) { lhsValue = ConditionalProperty.boolValue; } else if (ConditionalProperty.propertyType == SerializedPropertyType.Enum) { lhsValue = ConditionalProperty.enumNames[ConditionalProperty.enumValueIndex]; } else throw new Exception("Type needs implementing"); test = Check(lhsValue, bute.Operator, bute.RHSValues); if (bute.BetweenElementsLogic == null) { return test; } if (i != 0 && test && bute.BetweenElementsLogic[i - 1] == (int)ConditionalAttribute.LogicEnum.AND) { if (!previous) { test = false; } } if (test && i < bute.BetweenElementsLogic.Length && bute.BetweenElementsLogic == ConditionalAttribute.LogicEnum.OR) { return true; } previous = test; } return previous; } protected bool Check(object LHS, ConditionalAttribute.OperatorEnum op, object RHS) { if (!(LHS is IComparable) || !(RHS is IComparable)) throw new Exception("Check using non basic type"); switch (op) { case ConditionalAttribute.OperatorEnum.Equals: return ((IComparable)LHS).CompareTo(RHS) == 0; case ConditionalAttribute.OperatorEnum.NotEqualTo: return ((IComparable)LHS).CompareTo(RHS) != 0; case ConditionalAttribute.OperatorEnum.EqualsOrGreaterThan: return ((IComparable)LHS).CompareTo(RHS) >= 0; case ConditionalAttribute.OperatorEnum.EqualsOrLessThan: return ((IComparable)LHS).CompareTo(RHS) 0; case ConditionalAttribute.OperatorEnum.LessThan: return ((IComparable)LHS).CompareTo(RHS) < 0; default: break; } return false; }}
  7. OMG YOU REMBERED, THAT WAS MY THREAD :')   -- im satisfied so long as I get my kiss
  8. Scrambled or fried?
  9. I almost deleted all .png's from my C drive once. That was a scary day at work. :)
  10. washu wrote me this :) struct beufint_t { public: beufint_t () : t(et::n), u(0) {} beufint_t (bool b) : t(et::b), b(b) {} beufint_t (float f) : t(et::f), f(f) {} beufint_t (int i) : t(et::i), i(i) {} beufint_t (unsigned u) : t(et::u), u(u) {} operator bool () const { return t == et::b ? b : false; } operator int () const { return t == et::i ? i : 0; } operator float () const { return t == et::f ? f : 0; } operator unsigned () const { return t == et::u ? u : 0; } operator void const * () const { return t != et::n ? this : 0; } bool operator () (bool) const { return t == et::b; } bool operator () (int) const { return t == et::i; } bool operator () (float) const { return t == et::f; } bool operator () (unsigned) const { return t == et::u; } private: enum class et { b, f, i, u, n }; union { bool b; float f; int i; unsigned u; }; et t; };
  11. Ladies and gentle men, I bring to you, the Binteger (bool + int).
  12. turns out I wasn't banned. but when I tried to join multiple times, it said I didn't hqave permission :(