Jump to content

  • Log In with Google      Sign In   
  • Create Account

alnite

Member Since 07 Nov 2002
Offline Last Active Aug 28 2016 05:03 AM

#5308281 Transitioning from game development to business development with C#

Posted by on 27 August 2016 - 05:24 PM

Going into non-gaming jobs have its pros and cons.  An advanced knowledge of C# in Unity carries almost no value whatsoever in non-gaming tech industry.

 

Let me tell you how these people think.

1. Your worth as an engineer has nothing to do with how smart you are in solving a problem.  You have an O(log N) solution?  Not relevant.

2. What about your wealth of portfolio of sweet and fun games you have made with zero bugs! You know, the work that you spent countless hours and days and weeks and months to finish?  Not relevant.

3. What about your passion in fine tuning the animations, timing, and pacing of the games that you create?  You even created your own mathematical formula for that enemy movement!! Nope, not relevant.

4. What about your C/C++ knowledge of low level pointer manipulation?  You know your bits very well.  Not relevant.

 

Yup, all that thrown out the window.  Pfft.  Nobody cares about that in the tech industry.

 

Here's what they care about.

 

1. Language/framework skills.  Ever seen those job ads for "Software Engineer"?  What are the things they ask for?  Language and/or frameworks.  Do you know Java?  Do you know Rails?  Do you know SQL?  Do you know XYZ Big Big Data FizzBuzz Enterprise for Deep Learning Solutions?  Yes?  You are hired!

2. ....Nothing else

 

This is why there is soo much hype around new frameworks.  "ZOMG React is da best".  These guys rely heavily on the language and frameworks that they use to get the job done.  If you are a smart programmer using C/C++/Python, and I mean really smart like some members here, you are going to have a hard time landing a job on a company that's using Javascript/NodeJS.  I have been denied a job for stating "Rails sucks" (obviously they were using Rails) during the interview even though I aced all questions.  I know Ruby very well and even presented them an alternative solution in Ruby that's not Rails.  Nope nope nope.

 

Really.  That's how these people think and operate.  The term "tech stack" is popular for a reason, and zealotry over a particular language or framework is rampant.  It's like going back to gamedev when people were asking about DirectX vs OpenGL, except this is continuously happening on the global scale, and for every new language out there, new zealots are born.

 

That's why there are accelerated coding schools popping out all over the country like General Assembly, which BTW produce really really crappy engineers.  The scary thing is, companies actually hire them.  Get some no-clue-joe with zero programming background to spend 3 months learning Rails, oh you get yourself a Ruby on Rails Software Engineer.  I used to think all tech engineers are smart.  I was wrong.  They are engineers with a very specific domain knowledge, sometimes with an audacity to claim that Coding is Over(1)

 

You are most likely to land a job as a C# developer doing some websites in C#.  Even though C# and Java is very close, you'd be very lucky to find an employer that wants to hire you as a Java Developer, which means they might also be desperate and perhaps have an old ugly yucky Java code lying around that nobody wants to look at but you.

 

Don't get me wrong, there are exceptional engineers out there working in tech space.  After 6 years, I can still count them with my fingers, and there are still less than 5 so far.

 

 

Edit: Where's the formatting buttons?

 

(1) https://medium.com/@loorinm/coding-is-over-6d653abe8da8#.vhfpy1gqi




#5307776 What to consider for an RPG damage formula?

Posted by on 24 August 2016 - 11:47 PM

I wouldn't sweat it much.  Do test it, since different games need different formulas.

Starcraft (the original), as an example, has very simple methods, but it works for that game.




#5304748 Ide For Linux

Posted by on 08 August 2016 - 03:23 PM

I think the kind of workflow you would do on Linux is slightly different than on Windows.  On Linux, I am expected to know my way around the unix directories, know which files to edit, know how to tweak the system settings, all through the console.  So, therefore something like Vim would make more sense.  It's a fully customizable text editor that comes in most Linux installation, runnable from the console.  If I have to alt+tab from my fully-featured GUI-based IDE to my console, to do these little Linux hocus pocus sudobacadabra, back and forth, it's just less smooth.

 

I do my development on Vim and tmux, and I find it sufficient.  I am not doing any game development at the moment, just FYI, so my need may differ from yours.




#5297471 Is there any reason to prefer procedural programming over OOP

Posted by on 21 June 2016 - 11:38 AM

Lots of great points here.  It really comes to what problem you are solving, and in order to be able to identify when to use what, you'd need experience.  Here's something that I came across not too long ago at work that I solved using procedural.

 

The problem that I was solving was related to caching:

1. Get value from cache

2. If not available in cache, get it from database

3. Then store the value from the database to the cache

 

In Ruby, you can pass an anonymous function to another function.  The function that receives this anonymous function may decide (or not) to invoke.  This is what the function roughly looks like:

 

def get_from_cache(key, &block)
  value = cache.get(key)
  return value if value
 
  value = block.call # call the anon function
  cache.set(key, value)
  return value
end

 

The function is simple enough.  Attempt to get value from cache, if found, return value immediately.  If cache doesn't have the key, invoke another function, and use that function's return value as the value for the key.

 

We can 'chain' this up, creating complex logic structure.  Examples:

 

# Get value from database and cache it
value = get_from_cache("foo") do
  get_from_database("foo")
end
 
# Get value from HTTP and cache it
value = get_from_cache("foo") do
  http("http://www.gamedev.net/posts?key=foo")
end
 
# Or multiple caching layers
value = get_from_cache("foo") do
  get_from_another_cache("foo") do
    get_from_database("foo") do
      http("http://www.gamedev.net/posts?key=foo")
    end
  end
end
 




#5297341 Non-duplicating pairs from a set

Posted by on 20 June 2016 - 12:45 PM

Need to be elaborated more.

 

If it's 6 pairs from a set of 13 numbers, then one of the world won't have any portal at a given time, correct?

 

Gen 0, your set will look like this: [0,1], [2,3], [4,5], [6,7], [8,9],[10,11]

World 12 does not have a portal open.

 

Then, what's the rule for picking the next set?  Is it sequential?  Does this mean that world 0 will always be given the priority to pick the next world?  And World 12 will be lonely until the 12th generation.

 

Example:

Gen 1, set looks like this: [0,2], [1,3], [4,6], [5,7], [8,10], [9, 11].  In which case 12 is lonely again.

Gen 2, set looks like this: [0,3], [1,2], [4,7], [5,6], [8,11], [9, 10].  In which case 12 is lonely again.

 

Edit:

 

Here's a proposal.  Use a queue/stack depending on what order you want them to be, and each world needs to keep track a list of worlds that it has had a portal open to until next reset.  Initially your queue is just the sequence of the world.

 

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

 

Then, pop each world, if there's no world popped yet, keep this world 'open'.  Then pop the next world.  Attempt to link these two worlds together.  If two worlds have been linked together before, then it should fail the linking process, and you would have two worlds 'open'.  Repeat for the next world.  If pairing happens, "close"/"linked" both worlds.  Example:

 

Gen 0

 

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Pop #0.  Open: [0], Queue: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Pop #1.  Linked: [0, 1], Queue: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Pop #2.  Linked: [0, 1], Open: [2], Queue: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

and so on.. until the last one

Pop #11. Linked: [0,1], [2,3], [4,5], [6,7], [8,9], [10,11]. Queue: [12]

 

Gen 1

Reinserts all world back to the queue:

 

Queue: [12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Pop #12.  Open: [12], Queue: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Pop #0.  Linked: [12, 0], Queue: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Pop #1.  Linked: [12, 0], Open: [1], Queue: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

and so on.. until the last one

Pop #10. Linked: [12,0], [1,2], [3,4], [5,6], [7,8], [9,10]. Queue: [11]

 

Gen 2

Reinserts all world back to the queue:

 

Queue: [11, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Pop #11.  Open: [11], Queue: [12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Pop #12.  Linked: [11, 12], Queue: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Pop #0.  Linked: [11, 12], Open: [0], Queue: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Pop #1.  Linked: [11, 12], Open: [0], Open [1], Queue: [2, 3, 4, 5, 6, 7, 8, 9, 10]  // since [0,1] has been linked before

and so on.. until the last one

Pop #9. Linked: [11, 12], [0,2], [1,3], [4,6], [5,7], [8,10]. Queue: [9]

 

Gen 3

Queue: [9, 11, 12, 0, 2, 1, 3, 4, 6, 5, 7, 8, 10]

Final Order: [9, 11], [12, 2], [0, 3], [1, 4], [6, 8], [5, 10], [7]

 

 

You can get different linking order by playing around with different insertion order.  I am using the ordering of pairs, you can keep it sequential.  You can also use a stack instead of a queue.  I am using a queue so that the world that didn't get a portal open from previous generation would always get one at the next generation.

 

-- More edit:

 

Here's a list of all the portals:

 

Gen: 0
Queue Before: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Linked: [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [10, 11]]
Queue After: [12]
Link History: {0=>[1], 1=>[0], 2=>[3], 3=>[2], 4=>[5], 5=>[4], 6=>[7], 7=>[6], 8=>[9], 9=>[8], 10=>[11], 11=>[10], 12=>[]}

Gen: 1
Queue Before: [12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Linked: [[12, 0], [1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
Queue After: [11]
Link History: {0=>[1, 12], 1=>[0, 2], 2=>[3, 1], 3=>[2, 4], 4=>[5, 3], 5=>[4, 6], 6=>[7, 5], 7=>[6, 8], 8=>[9, 7], 9=>[8, 10], 10=>[11, 9], 11=>[10], 12=>[0]}

Gen: 2
Queue Before: [11, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Linked: [[11, 12], [0, 2], [1, 3], [4, 6], [5, 7], [8, 10]]
Queue After: [9]
Link History: {0=>[1, 12, 2], 1=>[0, 2, 3], 2=>[3, 1, 0], 3=>[2, 4, 1], 4=>[5, 3, 6], 5=>[4, 6, 7], 6=>[7, 5, 4], 7=>[6, 8, 5], 8=>[9, 7, 10], 9=>[8, 10], 10=>[11, 9, 8], 11=>[10, 12], 12=>[0, 11]}

Gen: 3
Queue Before: [9, 11, 12, 0, 2, 1, 3, 4, 6, 5, 7, 8, 10]
Linked: [[9, 11], [12, 2], [0, 3], [1, 4], [6, 8], [5, 10]]
Queue After: [7]
Link History: {0=>[1, 12, 2, 3], 1=>[0, 2, 3, 4], 2=>[3, 1, 0, 12], 3=>[2, 4, 1, 0], 4=>[5, 3, 6, 1], 5=>[4, 6, 7, 10], 6=>[7, 5, 4, 8], 7=>[6, 8, 5], 8=>[9, 7, 10, 6], 9=>[8, 10, 11], 10=>[11, 9, 8, 5], 11=>[10, 12, 9], 12=>[0, 11, 2]}

Gen: 4
Queue Before: [7, 9, 11, 12, 2, 0, 3, 1, 4, 6, 8, 5, 10]
Linked: [[7, 9], [11, 2], [12, 3], [0, 4], [1, 6], [8, 5]]
Queue After: [10]
Link History: {0=>[1, 12, 2, 3, 4], 1=>[0, 2, 3, 4, 6], 2=>[3, 1, 0, 12, 11], 3=>[2, 4, 1, 0, 12], 4=>[5, 3, 6, 1, 0], 5=>[4, 6, 7, 10, 8], 6=>[7, 5, 4, 8, 1], 7=>[6, 8, 5, 9], 8=>[9, 7, 10, 6, 5], 9=>[8, 10, 11, 7], 10=>[11, 9, 8, 5], 11=>[10, 12, 9, 2], 12=>[0, 11, 2, 3]}

Gen: 5
Queue Before: [10, 7, 9, 11, 2, 12, 3, 0, 4, 1, 6, 8, 5]
Linked: [[10, 7], [9, 2], [11, 3], [12, 4], [0, 6], [1, 8]]
Queue After: [5]
Link History: {0=>[1, 12, 2, 3, 4, 6], 1=>[0, 2, 3, 4, 6, 8], 2=>[3, 1, 0, 12, 11, 9], 3=>[2, 4, 1, 0, 12, 11], 4=>[5, 3, 6, 1, 0, 12], 5=>[4, 6, 7, 10, 8], 6=>[7, 5, 4, 8, 1, 0], 7=>[6, 8, 5, 9, 10], 8=>[9, 7, 10, 6, 5, 1], 9=>[8, 10, 11, 7, 2], 10=>[11, 9, 8, 5, 7], 11=>[10, 12, 9, 2, 3], 12=>[0, 11, 2, 3, 4]}

Gen: 6
Queue Before: [5, 10, 7, 9, 2, 11, 3, 12, 4, 0, 6, 1, 8]
Linked: [[5, 9], [10, 2], [7, 11], [3, 6], [12, 1], [4, 8]]
Queue After: [0]
Link History: {0=>[1, 12, 2, 3, 4, 6], 1=>[0, 2, 3, 4, 6, 8, 12], 2=>[3, 1, 0, 12, 11, 9, 10], 3=>[2, 4, 1, 0, 12, 11, 6], 4=>[5, 3, 6, 1, 0, 12, 8], 5=>[4, 6, 7, 10, 8, 9], 6=>[7, 5, 4, 8, 1, 0, 3], 7=>[6, 8, 5, 9, 10, 11], 8=>[9, 7, 10, 6, 5, 1, 4], 9=>[8, 10, 11, 7, 2, 5], 10=>[11, 9, 8, 5, 7, 2], 11=>[10, 12, 9, 2, 3, 7], 12=>[0, 11, 2, 3, 4, 1]}

Gen: 7
Queue Before: [0, 5, 9, 10, 2, 7, 11, 3, 6, 12, 1, 4, 8]
Linked: [[0, 5], [2, 7], [9, 3], [10, 6], [11, 1], [12, 8]]
Queue After: [4]
Link History: {0=>[1, 12, 2, 3, 4, 6, 5], 1=>[0, 2, 3, 4, 6, 8, 12, 11], 2=>[3, 1, 0, 12, 11, 9, 10, 7], 3=>[2, 4, 1, 0, 12, 11, 6, 9], 4=>[5, 3, 6, 1, 0, 12, 8], 5=>[4, 6, 7, 10, 8, 9, 0], 6=>[7, 5, 4, 8, 1, 0, 3, 10], 7=>[6, 8, 5, 9, 10, 11, 2], 8=>[9, 7, 10, 6, 5, 1, 4, 12], 9=>[8, 10, 11, 7, 2, 5, 3], 10=>[11, 9, 8, 5, 7, 2, 6], 11=>[10, 12, 9, 2, 3, 7, 1], 12=>[0, 11, 2, 3, 4, 1, 8]}

Gen: 8
Queue Before: [4, 0, 5, 2, 7, 9, 3, 10, 6, 11, 1, 12, 8]
Linked: [[4, 2], [0, 7], [5, 3], [9, 6], [10, 1], [11, 8]]
Queue After: [12]
Link History: {0=>[1, 12, 2, 3, 4, 6, 5, 7], 1=>[0, 2, 3, 4, 6, 8, 12, 11, 10], 2=>[3, 1, 0, 12, 11, 9, 10, 7, 4], 3=>[2, 4, 1, 0, 12, 11, 6, 9, 5], 4=>[5, 3, 6, 1, 0, 12, 8, 2], 5=>[4, 6, 7, 10, 8, 9, 0, 3], 6=>[7, 5, 4, 8, 1, 0, 3, 10, 9], 7=>[6, 8, 5, 9, 10, 11, 2, 0], 8=>[9, 7, 10, 6, 5, 1, 4, 12, 11], 9=>[8, 10, 11, 7, 2, 5, 3, 6], 10=>[11, 9, 8, 5, 7, 2, 6, 1], 11=>[10, 12, 9, 2, 3, 7, 1, 8], 12=>[0, 11, 2, 3, 4, 1, 8]}

Gen: 9
Queue Before: [12, 4, 2, 0, 7, 5, 3, 9, 6, 10, 1, 11, 8]
Linked: [[12, 7], [2, 5], [4, 9], [0, 10], [6, 11], [3, 8]]
Queue After: [1]
Link History: {0=>[1, 12, 2, 3, 4, 6, 5, 7, 10], 1=>[0, 2, 3, 4, 6, 8, 12, 11, 10], 2=>[3, 1, 0, 12, 11, 9, 10, 7, 4, 5], 3=>[2, 4, 1, 0, 12, 11, 6, 9, 5, 8], 4=>[5, 3, 6, 1, 0, 12, 8, 2, 9], 5=>[4, 6, 7, 10, 8, 9, 0, 3, 2], 6=>[7, 5, 4, 8, 1, 0, 3, 10, 9, 11], 7=>[6, 8, 5, 9, 10, 11, 2, 0, 12], 8=>[9, 7, 10, 6, 5, 1, 4, 12, 11, 3], 9=>[8, 10, 11, 7, 2, 5, 3, 6, 4], 10=>[11, 9, 8, 5, 7, 2, 6, 1, 0], 11=>[10, 12, 9, 2, 3, 7, 1, 8, 6], 12=>[0, 11, 2, 3, 4, 1, 8, 7]}

Gen: 10
Queue Before: [1, 12, 7, 2, 5, 4, 9, 0, 10, 6, 11, 3, 8]
Linked: [[1, 7], [12, 5], [9, 0], [4, 10], [2, 6]]
Queue After: [11, 3, 8]
Link History: {0=>[1, 12, 2, 3, 4, 6, 5, 7, 10, 9], 1=>[0, 2, 3, 4, 6, 8, 12, 11, 10, 7], 2=>[3, 1, 0, 12, 11, 9, 10, 7, 4, 5, 6], 3=>[2, 4, 1, 0, 12, 11, 6, 9, 5, 8], 4=>[5, 3, 6, 1, 0, 12, 8, 2, 9, 10], 5=>[4, 6, 7, 10, 8, 9, 0, 3, 2, 12], 6=>[7, 5, 4, 8, 1, 0, 3, 10, 9, 11, 2], 7=>[6, 8, 5, 9, 10, 11, 2, 0, 12, 1], 8=>[9, 7, 10, 6, 5, 1, 4, 12, 11, 3], 9=>[8, 10, 11, 7, 2, 5, 3, 6, 4, 0], 10=>[11, 9, 8, 5, 7, 2, 6, 1, 0, 4], 11=>[10, 12, 9, 2, 3, 7, 1, 8, 6], 12=>[0, 11, 2, 3, 4, 1, 8, 7, 5]}

Gen: 11
Queue Before: [11, 3, 8, 1, 7, 12, 5, 9, 0, 4, 10, 2, 6]
Linked: [[3, 7], [11, 5], [1, 9], [8, 0], [12, 10]]
Queue After: [4, 2, 6]
Link History: {0=>[1, 12, 2, 3, 4, 6, 5, 7, 10, 9, 8], 1=>[0, 2, 3, 4, 6, 8, 12, 11, 10, 7, 9], 2=>[3, 1, 0, 12, 11, 9, 10, 7, 4, 5, 6], 3=>[2, 4, 1, 0, 12, 11, 6, 9, 5, 8, 7], 4=>[5, 3, 6, 1, 0, 12, 8, 2, 9, 10], 5=>[4, 6, 7, 10, 8, 9, 0, 3, 2, 12, 11], 6=>[7, 5, 4, 8, 1, 0, 3, 10, 9, 11, 2], 7=>[6, 8, 5, 9, 10, 11, 2, 0, 12, 1, 3], 8=>[9, 7, 10, 6, 5, 1, 4, 12, 11, 3, 0], 9=>[8, 10, 11, 7, 2, 5, 3, 6, 4, 0, 1], 10=>[11, 9, 8, 5, 7, 2, 6, 1, 0, 4, 12], 11=>[10, 12, 9, 2, 3, 7, 1, 8, 6, 5], 12=>[0, 11, 2, 3, 4, 1, 8, 7, 5, 10]}

Gen: 12
Queue Before: [4, 2, 6, 3, 7, 11, 5, 1, 9, 8, 0, 12, 10]
Linked: [[4, 7], [5, 1], [2, 8], [11, 0], [6, 12], [3, 10]]
Queue After: [9]
Link History: {0=>[1, 12, 2, 3, 4, 6, 5, 7, 10, 9, 8, 11], 1=>[0, 2, 3, 4, 6, 8, 12, 11, 10, 7, 9, 5], 2=>[3, 1, 0, 12, 11, 9, 10, 7, 4, 5, 6, 8], 3=>[2, 4, 1, 0, 12, 11, 6, 9, 5, 8, 7, 10], 4=>[5, 3, 6, 1, 0, 12, 8, 2, 9, 10, 7], 5=>[4, 6, 7, 10, 8, 9, 0, 3, 2, 12, 11, 1], 6=>[7, 5, 4, 8, 1, 0, 3, 10, 9, 11, 2, 12], 7=>[6, 8, 5, 9, 10, 11, 2, 0, 12, 1, 3, 4], 8=>[9, 7, 10, 6, 5, 1, 4, 12, 11, 3, 0, 2], 9=>[8, 10, 11, 7, 2, 5, 3, 6, 4, 0, 1], 10=>[11, 9, 8, 5, 7, 2, 6, 1, 0, 4, 12, 3], 11=>[10, 12, 9, 2, 3, 7, 1, 8, 6, 5, 0], 12=>[0, 11, 2, 3, 4, 1, 8, 7, 5, 10, 6]}

Gen: 13
Queue Before: [9, 4, 7, 5, 1, 2, 8, 11, 0, 6, 12, 3, 10]
Linked: [[4, 11], [9, 12]]
Queue After: [7, 5, 1, 2, 8, 0, 6, 3, 10]
Link History: {0=>[1, 12, 2, 3, 4, 6, 5, 7, 10, 9, 8, 11], 1=>[0, 2, 3, 4, 6, 8, 12, 11, 10, 7, 9, 5], 2=>[3, 1, 0, 12, 11, 9, 10, 7, 4, 5, 6, 8], 3=>[2, 4, 1, 0, 12, 11, 6, 9, 5, 8, 7, 10], 4=>[5, 3, 6, 1, 0, 12, 8, 2, 9, 10, 7, 11], 5=>[4, 6, 7, 10, 8, 9, 0, 3, 2, 12, 11, 1], 6=>[7, 5, 4, 8, 1, 0, 3, 10, 9, 11, 2, 12], 7=>[6, 8, 5, 9, 10, 11, 2, 0, 12, 1, 3, 4], 8=>[9, 7, 10, 6, 5, 1, 4, 12, 11, 3, 0, 2], 9=>[8, 10, 11, 7, 2, 5, 3, 6, 4, 0, 1, 12], 10=>[11, 9, 8, 5, 7, 2, 6, 1, 0, 4, 12, 3], 11=>[10, 12, 9, 2, 3, 7, 1, 8, 6, 5, 0, 4], 12=>[0, 11, 2, 3, 4, 1, 8, 7, 5, 10, 6, 9]}
 

 

Notice that it takes 14 generations to go through them all (number of worlds + 1), and the last generation only has two portals open between #4-#11, and #9-#12, while the rest of the worlds are portal-less.  Depending on which is stricter requirements, you can keep it to 13 generations before reseting the link history just knowing that #4-#11 and #9-#12 will never have portals together.




#5296519 how can neural network can be used in videogames

Posted by on 14 June 2016 - 12:54 PM

Strange that nobody mentioned this:




#5293819 Designing UI library - positioning items in containers

Posted by on 27 May 2016 - 10:44 AM

It's been a while since I wrote my own UI library, but here's my opinion.  Take it with a grain of salt:

 

Preferred size/min/max

I am not in favor of preferred size, min, or max.  I think this pollutes the logic.  Consider two child items side by side, both with preferred size of 100.  Container is resized to 150, what is the size of each child item?  If your answer is 75, then why bother with preferred size at all?  Why have a parameter at all only to be ignored?

 

Instead, each child should be responsible in its own proper rendering and logic in any size.  By any size, I mean even down to 1x1 pixel.  No minimum size, no maximum size.  You have a button, that button better works even when its 1x1.  You have a radio button, it better works at 1x1.

 

You can enforce minimum size at the container level, but child item (which cannot contain another child) should be able to handle any size.  Object positioning should be handled by the container, and any items should not dictate to its container how it should be positioned, neither preferred, min, nor max.

 

The reason why is that I have worked on some custom UI library that follows this Java's swing approach, and it has these preferred size, min, and max etc, and they dictate the way the container align and position its children.  It's hard to resolve conflicts at the container level if the child items can dictate to its container how to position itself.  One child say my min is 100, another say my min is 150, and container is resized to 200, which one should you resize?

 

It gets worse if child items are engineered with these preferred, min and max in mind, that certain logic starts to fail when the size goes beyond or lower than these arbitrary thresholds.  "Since my size won't ever go lower than 100, right?, so I'll draw this 5x5 important UI element at exactly the 95th pixel"  Guess what, your width is now 80, and that important UI element is now gone.  Great.

 

So, no min, max, or preferred at all.  As a matter of fact, maybe let the container tells its children their size.




#5293813 Cloudhosting a C# Console Application utilizing UDP

Posted by on 27 May 2016 - 10:03 AM

Actually most server apps I know of lack of a UI frontend.  That does not mean it can't have a UI frontend, just depends on your use case.

 

There are a few server "engines" out there that's been mentioned several times like SmartFox, though I believe it's Java, and I am not sure if it's the 'goto' service.  And in regards to AWS to Azure, it comes to personal preference.  Do understand that once you choose one, you'd usually 'marry' that platform.  It'll be another engineering task to move from one to another.




#5293633 Do you usually prefix your classes with the letter 'C' or something e...

Posted by on 26 May 2016 - 12:31 PM

I tend to use verb/noun/adjective to describe methods, classes, and interface.  Collidable, for example, is an interface.  There are a few cases where it may not be immediately clear at first glance, in which case a simple "Go To Definition" would suffice.

 

The only prefix I use is underscore for reserved class/global variables that I certainly don't want conflicts to happen.  Because you have to be pretty deliberate to use an underscore as the first char.  Even that does not happen a lot.




#5292941 How should I develop this game?

Posted by on 22 May 2016 - 04:37 PM


because I know a single person with no team can't really do something good in this area

 

Actually, yes you can, but it does take a lot of time and dedication.

 

 


I want to develop an RPG game. It's not for me, or for many people. It's only for one special person. I have one month to do this, and I don't know where to start. 

The game would be a story that simulates the butterfly effect. The player will have many choices in many parts of the story, and choosing something will cause a different ending.

 

I think this is a little too much for a one-man one-month project.  Multiple ending paths isn't easy to do.  Being able to architect a game world where different actions lead to different things require a lot of iteration and testing.  You really have to know how to code a game well before taking this task, considering that you are new to game development.

 

If you are not familiar with game development, your initial struggle would be figuring out how animations, collisions, and different game mechanics work.  Different types of games require different technology.  For example, A* is not required for a fighting game, but maybe required for an RPG depending how you present it, and a very robust version is required for an RTS game.  What you need to learn and do really depend on what your game look like and how to play it.

 

So, scoping.  If you ask me, in one month, it's probably more feasible to do a pure text-based adventure game.




#5278639 best way to write clean code

Posted by on 29 February 2016 - 12:06 AM

1. DOTADIW

 

For example: If you have a function called "CreatePath()", make sure all that function does is create a path and nothing else.  Make sure you test it such that it can handle any combination of parameters and corner cases such that it has exactly ZERO (0) bugs.  "CreatePath" cannot call "CreateUnit" or any other functions that might dilute and increase its complexity.

 

 

2. Don't be afraid to refactor and rewrite parts of your code.

 

As you add more logic to your code, refactor is inevitable.  Don't wait to refactor until the last step.  One cause that leads to spaghetti code is people are afraid to create new bugs that they keep monkey-patching on top of what was originally a perfectly fine codebase.  I have been seeing this so many times in my professional life doing code review.  People are so afraid modifying an existing function to make implementation less complex, and would rather put another layer of complexity.

 

Me: "You can just edit that one function to accept an extra parameter, and it will be easier."

Them: "Well, I am not sure what it does and I don't want to break it" (or some other lame excuse like how he has to update the tests)

Me: "But now you just duplicated the code, and next developer will be confused which function to use"

 

 

 

3. Write Automated Tests

 

Test, test, test your code, and write a separate program to test your code.  In all my professional life, nothing have given me better confidence in my code until I have written automated tests for my code.  Sure, it's an annoying thing to do when you write your tests for the first time (ah geez, another shit to worry about), but the confidence you get from running one single command and have ALL your code tested and validated in less than a minute is just too good to pass up.

 

Follow #1 above to make it easier to write your unit tests.  Follow #1 above to make it easier to write functional tests.  If your code is a spaghetti, your tests will be a spaghetti too, and it will annoy the heck out of you.

 

 

4. Document Your Code

 

Another thing that most developers avoid (after writing tests) is writing documentation.  You HAVE TO write documentation to your code.  It sorts of gives your code that final conclusive stamp of approval and seal the envelope.  Writing documentation puts your mind into a 3rd person perspective.  I have found so many design flaws when writing documentation.  For example, let's say your CreatePath() function is badly written that it internally calls CreateUnit() and CreateEnemy().  Writing tests will make you aware of this, and writing documentation will make you reconsider what kind of parameters to accept to avoid calling CreateUnit() and CreateEnemy().

 

If tests make you aware about the internal working of your code, documentation makes you aware of how components in your code play with each other.  Writing documentation is a form of rubber ducky programming.  You are trying to explain to some other (imaginary or not) person who is clueless about how your code works.

 

 

#3 and #4 are your worst enemies.  Somehow developers avoid them like plague thinking they have godlike coding ability that no tests is ever required, and no documentation is ever necessary.  "Code should be self-documenting anyway" rolleyes.gif, I always laugh at that statement.




#5271790 Resolving Creative Differences

Posted by on 18 January 2016 - 10:51 PM

Who is in charge of what?

 

If you have done any game development professionally, you will learn that the game that comes out won't be the exact match of what you are thinking.  You have to let go the control sometimes.  This is not just your game.

 

When this kind of problem arises, usually people would do AB testing.  Create both, and see what works better.  Peer feedback is the most useful thing in video game development.  I am sorry to say that most likely your idea sucks, and so is his (and mine, and everyone else).  We rarely get the first implementation correct.  Peer feedback is important as it gives you honest reviews if game is fun or not.  You'd most likely end up with something completely different than any of you two could imagine.




#5265007 Why didn't somebody tell me?

Posted by on 05 December 2015 - 07:29 AM

There is a Search Tools in Google Search that allows you to filter results based on time.

 

One time someone in my office did this during a meeting and everyone was like "WAIT, YOU CAN DO THAT??"




#5264676 Indie Game Company Names

Posted by on 02 December 2015 - 06:49 PM

Zombie Rose (you know, rise, rose, risen, a little pun here.)




#5262769 Software Tool Selection Process - Improvements please

Posted by on 19 November 2015 - 01:05 PM

 


Unity wouldn't be here if the original developers decided to use an existing game engine

Unity was conceived from the very beginning as a middleware package - it wasn't like they built a game and spun the pieces into an engine after the fact.

 

Which makes it sort of an exception to this whole discussion. If your aim is to build brand-new middleware, then building from scratch is clearly indicated.

 

 

Maybe I misunderstood, but isn't it the discussion of this thread?  Given Software Tool X, shall I rewrite or use it?






PARTNERS