Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Bongo Bill
Jan 17, 2012

Today I got out and got some work done on my game. Still very early in development, but even having a small and clear list of things to implement now doesn't stop it from being hard to work from home when you're surrounded by all your favorite distractions. I may have to increase my coffee-house budget if I'm to meet my goal of a release by the end of the year.

I'm writing this in C with SDL SQLite mostly because I like like C and SDL and I'm likely to need to be familiar with SQLite at some point in the future, but this has the convenient property of being about as platform-independent as anything can be. The interface lends itself naturally to buttonless control as well, so, happily, if there's interest for it, mobile ports will be possible without extensive reworking. But that's a long ways out. Today I did exactly what I needed, which was to stop planning and start acting.

I also found Jeff Vogel's recent article about independent business practices to be quite inspiring.

Adbot
ADBOT LOVES YOU

Bongo Bill
Jan 17, 2012

poemdexter posted:

The problem with an AI developing a game is that you have to quantify "fun" and then create heuristics that create more fun. It's kind of like trying to teach a robot how to paint. You can tell it how to make the strokes, but you'll never be able to convey the concept of "art" to a machine.

Your heuristics for quantifying fun can be an art all their own, though.

Bongo Bill
Jan 17, 2012

Some games - roguelikes, mainly - do it by tuning the mechanics so that any possible output is sufficiently interesting content. Not all types of game can work well with the sort of super-dense style that implies, however.

Bongo Bill
Jan 17, 2012

No problem can be solved without first defining the problem in such a way that you can measure the effectiveness of the solution. Creativity hasn't been quantified, but there are several widely-used proxies for it; a machine can optimize for those proxies, crude as they are.

Machine learning hasn't been widely applied to game development, but it's going to become more common as game metrics increase in prominence. That particular field is mostly just really advanced statistics, so you need large datasets to use it effectively.

Bongo Bill
Jan 17, 2012

In most languages, standard output is global, right? Your canvas fulfills the same purpose as stdout, so it too should be accessible globally. (Though it isn't always idiomatic to simply declare it in global scope and call it a day.)

Bongo Bill
Jan 17, 2012

Shameproof posted:

If I want to do something text-based should I use TADS or just write my own program?

If what you want to do does not deviate extensively from the sort of game TADS (or Inform) is designed to make, then yes, use it! That's what it's there for.

Unless you really like reinventing wheels. I know I do.

Bongo Bill
Jan 17, 2012

LOVE is a very featureful Lua library intended for the development of 2D games. It provides 2D physics but I'm not sure how robust. It's a rather convenient little framework, flexible and powerful; I haven't been using it very long but I quite like it, and will recommend that you at least look into it.

Bongo Bill
Jan 17, 2012

Hanpan posted:

Yea my main tool is Unity and I absolutely love it. That said, no matter how many plugins you throw at, it's still primarily a 3D game based engine and the workflow for 2d games is kind of daft.

Perhaps I should give Pygame another shot, it's always seemed really slow to me, kind of like how Flash games 'feel'. Does it perform just as well as SDL would? I honestly didn't realise it was just a wrapper.

Thanks for the suggestions.

Last I heard, Pygame still had performance issues.

Bongo Bill
Jan 17, 2012

Gordon Cole posted:

Isn't SMB written in flash? Binding of Isaac is definitely flash and I'd say it's "action-y". You also don't need a dedicated IDE like FlashDevelop to write ActionScript, you can easily do it in something like TextMate.

Super Meat Boy isn't Flash.

Bongo Bill
Jan 17, 2012

roomforthetuna posted:

Does "HTML5" just imply "Javascript" these days? (Not snarking, curious because I've seen it in contexts like this before where clearly Javascript is necessary but goes unmentioned.)

Yes, but with the caveat that there are many tools that compile some other language to Javascript, with varying degrees of support for Javascript libraries. Things to look into include Coffeescript, lua.js, and emscripten, which all take different approaches.

Bongo Bill
Jan 17, 2012

I think it is possible to alter the behavior of the output from within the code for the game itself, though I don't know enough about the various IF-specific languages to tell you how to do it. What language were you using previously?

Bongo Bill
Jan 17, 2012

Relevant to the earlier discussion about talent and effort; effective practice is what creates expertise, and some are not so fortunate as to begin effectively. The self-reinforcing nature of certain skills means it's important to start well, but that's also the most pedagogically difficult part of the process.

Bongo Bill
Jan 17, 2012

For simple user interfaces in games, "immediate mode GUI" is a sane and frequently-used approach. Compared to conventional GUI libraries, IMGUI libraries are usually not as well-supported or featureful, and quickly get out of hand if you try to compose a complex interface out of them, but are a much more flexible and easy-to-use tool for smaller tasks, and usually integrate very smoothly into the structure of a game. Google might reveal that somebody has made an IMGUI library designed for use in whatever graphics library you're already using (SDL, SFML, etc.), and I believe Unity's built-in GUI is immediate mode.

Of course, nothing can stop user interface code from being very long, and managing the complexity of your main game loop is important. To keep it from being just one huge monolithic function of nested decisions, there are several strategies, each of which has tradeoffs of its own. I'll give you a basic overview of a few common ones, but following up with further reading elsewhere.

Any game is going to have to deal with the fact that most of its parts have different behaviors depending on their state. The use of finite state machines would be reasonable, though there are many different ways to implement those. In most games, every different state the game can be in is a "scene," and each scene has its own update and (sometimes) render function. It's up to you to decide how far to take this, but try starting with having the main menu and each level be a single scene. You will probably want your main game loop to be responsible for transitioning between scenes and managing which ones are currently instantiated. Structure your code so it can be reused - if most levels have basically the same logic and rendering, have them inherit or call the shared functionality rather than reimplementing it each time - and you should have an easier time keeping your code orderly.

Each scene can then itself manage the state machines responsible for each of the elements of the game. It's state machines all the way down. State machines can be implemented in many different ways. If you're working in an object-oriented language, you'll probably be better off implementing each scene as its own singleton class, whereas game elements that need to persist a lot of data between frames make more sense as just objects. Since the state of your user interface probably does not need to preserve a lot of data, it's possible to implement each state as a function (delegate, function pointer, whatever your language calls it). And I'm currently working on a project where, just for fun, I've implemented states as coroutines consisting mainly of nested infinite loops - that might be a bit esoteric for a beginner.

More complex games typically use an "entity component system," and in fact Unity gives you one of these for free, but implementing one from scratch would probably exceed what a single amateur game developer is capable of (or at least interested in). Think of it this way: everything in the game - every element of the simulation, every resource, every script, every input device, every camera - is an "entity," which is nothing more than a unique identifier. It has some way of being associated with "components," which are the data that cause those entities to mean something. MMORPGs typically serialize the entire game state by writing this all into a relational database (give or take lots and lots of optimizations). And all of the game logic that acts on that data is handled by "systems," which might have some state of their own but mainly just get only the components they specifically need, and perform logic with them. Even the renderer is just a system, acting on entities which have components representing visual data. Usually each system does its thing once per frame, but you can put them on separate threads and get parallelism very easily. This kind of structure scales up wonderfully, but its weaknesses are the complexity and overhead of the supporting structure, and the fact that there's no more elegant way to handle interdependencies between systems than having them pass messages around. A lot has been written about the entity component system pattern, and it's interesting stuff.

There are many different ways to handle the details of your game's architecture, but the relative advantages and disadvantages of any given approach aren't particularly compelling. In a hobby project involving one programmer and generous performance requirements, the best structure is the one that the programmer understands. This understanding comes from knowing what decisions you've made and why.

Procedural content generation is an entirely different thing, but you might find "Wang tiles" a good phrase to start with.

Bongo Bill
Jan 17, 2012

Procedurally generated content can be effective if that content is being consumed by a system which necessarily responds differently to differences in the content, but always works no matter what content is generated. That's a very difficult balance to strike, because it requires game mechanics that establish a dense and detailed possibility space without themselves being dense and detailed.

It can also work for generating content that makes no difference at all but which nevertheless needs to exist in vast quantities. Level layouts aren't an example of this kind of content, though.

Bongo Bill
Jan 17, 2012

Procedural World is a blog about one person's ongoing efforts to address this sort of problem. It's incredibly impressive, but for the specific context of dungeon generation, these two posts and their comments will definitely be a good starting point.

The short version is: you start with a bunch of prefabricated rectangular sections, "color"-coded according to their exits, then lay them out randomly so that they match. That's "Wang tiles" and they're a pretty basic concept. To make the patterns in them more interesting and harder to discern, you can make the tiles a different shape and lay them out in a more interesting pattern than just a rectangular grid; in the second post, the author links to a paper describing using Wang tiles in a herringbone pattern.

Of course, this leaves you with the problem of needing content with which to fill in the tiles. This is now a smaller problem than generating entire dungeons. All sorts of tools, from hundreds of hand-designed tiles to techniques like Perlin noise and genetic algorithms and even machine learning, can be applied to this end, but you're not going to make much progress without intimately understanding your own specific needs and the consequences of each approach. In terms of programming, however, probably it would be best to write a separate program to export all of your tiles to files or a database, which you then ship with the game and read at runtime when you run your tiling algorithm.

This may be overkill if you're just trying to make a plain old roguelike. If you want to see how other roguelikes have done it, many approaches are documented in the articles on Roguebasin. Run a search for "generation" and see what comes up.

Bongo Bill fucked around with this message at 00:37 on Apr 20, 2013

Bongo Bill
Jan 17, 2012

I've played around with Love2D, and it seems like a very well-made, well-maintained, and well-documented piece of software.

Bongo Bill
Jan 17, 2012

A checkerboard pattern, right? This isn't a way to approach it in code, but rather a way to think about it.

One thing you could do is think of your grid instead as an undirected graph. In this model, there are no dimensions - merely nodes in the graph, which contain a tuple that coincidentally corresponds with their eventual screen coordinates. You lose out on some of the specific features of defining a plane, as each node must be discrete and be specifically represented in memory, but arbitrary graphs are highly flexible, and pathfinding can still be done with A* (or, more likely, Dijkstra's Algorithm, which is a special case of A*, where all nodes are equally weighted).

Alternatively, if you need the advantages of a grid, simply rotate the whole thing 45 degrees, so that instead of a diagonal grid you're looking at an orthogonal one. For instance, the grid you already posted becomes this:

code:
                        <4,0> <5,1>
                  <3,0> <4,1> <4,2> <5,3>
            <2,0> <3,1> <3,2> <4,3> <4,4>
      <1,0> <2,1> <2,2> <3,3> <3,4>
<0,0> <1,1> <1,2> <2,3> <2,4>
      <0,2> <1,3> <1,4>
            <0,4>
However, one thing you'll note about doing it that way is that your coordinate system will have to be changed compared to your example. This might be for the best, as the current one is a bit inconsistent anyway. If you want to use spatial coordinates, then you need to be able to answer this question: given a set of coordinates, what are the coordinates of all the adjacent locations? And if you look at the sample grid you've posted, the algorithm that answers that question is rather complex: given a point <x,y> the adjacent points are {<x-1, y-1>, <x-1, y+1>, <x, y-1>, <x, y+1>} if x+y is even, or {<x, y-1>, <x, y+1>, <x+1, y-1>, <x+1, y-1>} if x+y is odd. Not only is this inconsistent, but sometimes the same delta can appear in these two sets, but representing different directions!

A third option would be to take the diagonal grid you've already got, but just use plain old orthogonal Cartesian coordinates, enforcing the invariant that the only valid positions on the grid are those where x + y is not odd. Once again you'd have to redo the coordinates.

Of course, since all the possible movements on this grid are orthogonal to each other, it's possible to use a simple Manhattan distance algorithm to calculate the distance between any two points - but, again, not with the coordinate system you posted. With something more logical, the distance between two points will simply be Δx + Δy, unless all the routes in between are blocked (which is where A* comes in).

Bongo Bill fucked around with this message at 07:43 on May 20, 2013

Bongo Bill
Jan 17, 2012

Fortunately, there is a solution! Let's go back to your original layout, but this time, let's add a little markup.

code:
[0,0] [1,0] [2,0] [3,0] [4,0]
   <1,1> <2,1> <3,1> <4,1> <5,1>
[0,2] [1,2] [2,2] [3,2] [4,2]
   <1,3> <2,3> <3,3> <4,3> <5,3>
[0,4] [1,4] [2,4] [3,4] [4,4]
When you look at it this way, it's clear that you've actually got two overlapping grids - one where Y is odd, which I've indicated with <angle brackets>, and one where Y is even, which I've indicated with [square brackets]. What distinguishes these two grids is the parity of Y.

You can still calculate the Manhattan distance between two points (X1, Y1) and (X2, Y2). The first thing you need to determine is whether the two points have the same parity or different parity. If the parity is the same, then it's simple: the distance is given by 2ΔX+ΔY. Try it and you'll see. If the parity is different, then it's more complicated.

However, there's still a pattern. In order to identify the pattern, I'm going to draw the same grid again, but this time, instead of the coordinates, I'm going to label it with the distance to an arbitrarily chosen point - in this case, [2,2]. I'll leave the brackets indicating parity as well.

code:
[4] [2] [2] [2] [4]
  <3> <1> <1> <3> <5>
[4] [2] [0] [2] [4]
  <3> <1> <1> <3> <5>
[4] [2] [2] [2] [4]
As you can see, the distance between two points of opposite parity will always be odd. (And, if you go look back above, the distance between two points of equal parity, given by 2ΔX+ΔY, will always be even because ΔY is always even in this case, as the parity of ΔY determines the parity of the distance!)

Having perceived this pattern, there are several ways to approach it. What stands out to me is that if you take your point (X1, Y1) and select an adjacent point (X1', Y1') that is in the same direction as (X2, Y2) - in other words, "move" southwest if the target is not northeast, northeast if the target is not southwest, northwest if the target is not southeast, and southeast if the target is not southwest - then the distance between opposite-parity points (X1, Y1) and (X2, Y2) is equal to the distance between equal-parity points (X1', Y1') and (X2, Y2) + 1, which is to say, 2ΔX+ΔY+1.

An interesting property of this calculation is that you can simply select each of the four adjacent points to the start, calculate the distance from there to the end, and add 1 to whichever is least. But it might be more efficient if you know in advance which is closest.

There are other ways to approach it. This solution, for instance, does not take into account the fact that even and odd coordinates have different definitions for the relative cardinal points, and you will need to know that one way or another.

Bongo Bill fucked around with this message at 08:18 on May 20, 2013

Bongo Bill
Jan 17, 2012

That would be best, but unfortunately,

Mug posted:

It's WAY too late to change the grid layout.

Bongo Bill
Jan 17, 2012

roomforthetuna posted:

Out of curiosity, how is Binding of Isaac trying to do way too much? I mean, I realize it runs like poo poo when there's about 10 things on screen, and then has horrendous controls-lag, but is ActionScript 2 really not capable of doing that kind of stuff properly, or was it just a consequence of the programmer not really being a programmer? I had assumed the latter, because there are loads of games on Kongregate that handle more going on at once, but I don't know if AS3 is a shitload better than AS2 or what.

The Binding of Isaac runs up against some sort of size limitation inherent to Flash; literally nothing more can be added to it, or it will fail to compile. I think that's more a matter of assets than code, as it wasn't explained in detail, but either way it's a very complex program. AS2 is Turing-complete, of course, but not all languages make things like this equally easy.

(That's why the team is working on a native remake+expansion.)

Bongo Bill
Jan 17, 2012

Take advantage of existing anatomical concepts. Say that the dark magic that animates them creates invisible, intangible muscles and more importantly tendons, which are like real ones in that they can be torn with enough force. If one of the bones is too far away from the others, the magic can't reach. If you add more magic, the sinews will mend themselves. The more magical the magic, the more tension the tendons can withstand.

Choose one bone at random and make that one the "core" bone. Only bones that are connected to that one will move. The skull, the sternum, or one of the vertebrae will be common choices, whereas the pelvis might be funny, and the ulna or humerus means you can have disenskeletoned hands crawling across the ground occasionally. If it's the third phalange or third metacarpal, then secretly make it a stronger skeleton than usual.

Bongo Bill
Jan 17, 2012

Lord Windy posted:

And it confuses the hell out of me. I really wish they kept it [][], even if whatever they replaced [][] with is really useful.

[][] still exists. Use [][] for nested containers (whose children cannot necessarily be assumed to have the same length) and [,] for multi-dimensional containers (where you often do wish it to be understood that the entire range is valid across the entire domain and vice versa).

Bongo Bill
Jan 17, 2012

What language is that? It seems to me like that would be performing 4-6 comparisons each time it's evaluated, depending on whether AND short-circuits. You can reduce the number of comparisons with ugly nested ifs like this:

code:
IF ax > ay THEN
  IF ax > az THEN
    'x is dominant
  ELSE
    'z is dominant
  END IF
ELSE
  IF ay > az THEN
    'y is dominant
  ELSE
    'z is dominant
  END IF
END IF
Walk through it yourself and you'll see this gives you exactly two comparisons each time, even though it's more verbose and less legible (that's what comments are for).

I don't know if the language supports this construct, but if it does, it would be more readable than your solution, and almost as efficient as mine.
code:
SELECT CASE MAX(az, ay, az)
  CASE ax 'x is dominant
    'trace a ray
  CASE ay 'y is dominant
    'trace a ray
  CASE az 'z is dominant
    'trace a ray
END SELECT
Alternate optimizations may be possible depending on exactly what it is you do in your "trace a ray" step.

Bongo Bill
Jan 17, 2012

Approach it from the perspective of finding a good way to load the game data, rather than save it.

Also, decide whether you want to serialize the entire game state, or just enough to be able to recreate the relevant parts. This decision involves engineering tradeoffs (such as preserving compatibility between versions) and game design concerns.

Bongo Bill
Jan 17, 2012

Orzo posted:

What do you mean by that?

C# doesn't makes it easier than, say, C to get away with not knowing where your data is located, when it's being copied, how hard it is to access, and other such details. However, you have to care about such things when optimizing algorithms and data structures of this sort.

Bongo Bill
Jan 17, 2012

Favor a flatter type hierarchy. Have just an Item class, with data members indicating that it can be equipped by sword users, that it has a sword icon, that it is called a Sword, what its stats are, etc.

Bongo Bill
Jan 17, 2012

SupSuper posted:

You gotta be careful with this though. You don't want to end up with a blob Item class that can represent everything from a sword to a pair of pants. Distinct behaviors should have distinct classes (either by inheritance or composition or etc).

On the contrary, in some cases you do want to dispense with all pretense of object-oriented design and make everything from the items in your inventory to the UI out of completely generic Entities. This is not suitable for every type of game, however.

Bongo Bill
Jan 17, 2012

Flashing Twelve posted:

I'm finding myself falling into a recurring design pattern. I'll create some entities of a certain type, let's say a door. However, other parts of the game have some common needs referring to the set of all doors (for example, 'find the closest door' or 'get a list of all unopened doors''). This leads to me creating a 'DoorManager', which ends up being a singleton that contains a list of all doors in the game and some (usually static) methods on it. What's the way out of this?

You could get more enterprise about it: have a singleton "ManagerFactory" which keeps a reference to your game state, and any other shared dependencies, and does nothing but instantiate (or otherwise provide; it may be better to instantiate them all up front) these managers as needed by any client. Hide every type involved behind interfaces so that you can create mock versions as needed.

Alternatively, get more functional, and create a static, stateless class (possibly with static instances of static, stateless internal classes, for organization's sake) whose static methods perform lookups of this sort given the game state and the other necessary parameters of the query (e.g. the location of the door-seeking game entity and anything else that might modulate the results) without modifying them.

Dependency injection is the order of the day here.

Bongo Bill
Jan 17, 2012

Mug posted:

What are the variables i j and k?

i is the imaginary number, i. j and k are additional imaginary numbers that work like i, but also there are rules for how all three of them interact with each other. The complex numbers you are familiar with define a two-dimensional space; quaternions define a four-dimensional space.

Bongo Bill
Jan 17, 2012

I don't think I can be considered a game developer considering it's been years since I successfully developed a game and I don't even have the spare time to pursue it as a hobby these days, but what the hell. Here's some useless answers.

1. Do you use a particular framework to develop your games, or do you roll your own engine? If the former, which one(s)? If the latter, what drove the design and development of that engine?

What I have done, I did from scratch even though I know I'd be making
my life more difficult. I do it because I like to see all the parts of the program come together and I'm in it to learn about the tools that I'm using. Usually once I've satisfied my curiosity or gotten distracted by something else, I move on and leave it unfinished.

2. Do you have any formal training in game development, such as a college degree, or are you primarily self-learned?

My college education had some game-focused courses because it was trendy at the time, but it was pretty much ordinary computer science. I've been diligent in keeping up with publications on the craft, however. Although formally educated in that sense, most of what I know about software generally and about games specifically is self-taught.

3. Do you work in the gaming (as in video games, not gambling) industry? If not, would you want to work in the gaming industry?

I don't. If there were a mythical version of the game industry that could guarantee a 40-hour workweek, I'd be interested, though. Game development is full of interesting challenges.

4. Have you studied design theory in the context of game design? If so, how have you incorporated it into your games? What resources have you used?

I'm not sure what this means.
I think the answer is Yes, though.

5. Are your games open source? If not, are they at least publicly available on version control sites like Github?

They would be if I got them to a releasable state. BSD-licensed.

6. Have you studied the source code or design documents of other games, e.g. the Quake 3 source code? If so, what have you learned from doing so?

I have pored over some of the id tech engines, but you can't expect me to remember the significance of everything I did in college. I'd probably learn a lot more from it if I went back to it today, though.

7. What do you feel is the largest problem (or problems) in game dev these days? What do you feel could help alleviate these problems?

Everybody else has given very insightful answers from the standpoints of professionals on projects of varying sizes. From my perspective as a creepy outsider leering in from the bushes by game development's back fence, I think that a lot of the current difficulties are related to the apparent fact that next to nobody knows how to sell a video game. We've gotten very good at selling video games, but specific ones, not so much.

In the AAA space you have big titles with a cross-media marketing push that amounts to "Hey, this thing exists," which is effective and gets people excited when it's big enough, but strongly emphasizes aesthetic elements and heavily targets consumers who already know it exists. Indies just have to join this groundswell of opportunity and hope to go viral, and crowdfunding complicates things even further, because that's hype-based marketing and a hype cycle cannot be sustained for the length of time it takes to develop a game commensurate to the enthusiasm. The mobile space has raced to the bottom of its own tarpit due to the total inadequacy of generic storefronts as a curation, recommendation, and discovery tool. I think these are all problems just waiting to be solved.

8. Do you follow a design and iteration process, formalized or otherwise, for developing your games?

In practice, yes, in that every aborted project converges on the same few ideas I've been daydreaming since I was nine years old. In theory, no, because you've got to iterate at least once in order for it to be considered a process.

Bongo Bill
Jan 17, 2012

Zaphod42 posted:

You can't have a const parameter or return in C# nah, but you can have regular constant variables. So what you could do is have an interface, and then have a non-constant version of the class and a constant version of the class, and have a copy constructor for the constant version which accepts the non-constant version as a parameter. That's a bit roundabout though.

Alternatively wrap it in a ReadOnlyCollection<>.

Make an interface for the class which has all getters and no setters, and if you've got a List<MyClass>, make a public accessor that returns an ImmutableList<IMyClass> using AsReadOnly(), and trust the callers not to cast them back to MyClass. However, if any of the members of IMyClass have public methods that mutate them, those can still be changed.

Bongo Bill
Jan 17, 2012

"var" just instructs the compiler to infer the type of the binding based on the return type of whatever you assign to it. It's very convenient when you're dealing with generic types, which can have very long type signatures. Sometimes, however, you want to specify that you intend for the binding to be a less specific type than what you actually get. Additionally, being explicit has benefits for understanding whether the program is doing what you want it to do; it allows you to see instantly what type the variable is, and forces you to think earlier about whether that's the right type.

The largest effect is has is on readability, which means this is a question of coding style. It improves readability by curtailing repetition of type names and reducing the verbose specification of lengthy types for unimportant intermediate values, but it hinders readability by forcing the reader to infer the type of the variable rather than specifying it directly. Like any time you're talking about style, choosing the "best" style matters far less than consistently adhering to a minimally sane one. Just be aware of the tradeoff you choose.

Bongo Bill
Jan 17, 2012

you just write that code any old way you want and the good Lord shall provide

Bongo Bill
Jan 17, 2012

The Unity alternative in C#-land is Monogame, which is the successor to XNA.

Bongo Bill
Jan 17, 2012

Lua is dynamically typed, like Javascript and Python. Dynamic typing encourages a different style of program design than static typing does, and if you try to use approaches designed for statically typed languages (like, say, just about anything to do with OOP) you will encounter friction.

At a high level, dynamic typing is more flexible when writing and designing but at the cost of making maintenance much more difficult the larger the program gets. Nontrivial programming tasks will involve a lot more maintenance than writing, too, so for that reason it's difficult to recommend writing an entire game in Lua. However, for small programs, or very well-encapsulated components, it makes a lot of sense to write small scripts in a dynamic language (with limited access to the larger program if there is one). That's why they position Lua as a scripting language. You'll have the best luck if you don't try to use anything heavier than plain old tables and functions.

For simple games - or, more accurately, for games with simple user interfaces and simple game entities - it can be very economical to define the game logic all in a scripting language. That's where Love2D excels, and why it's had the most success as a prototyping tool rather than as an engine for commercial products. As a bonus, Lua syntax is fairly ergonomic for data definition, so it can also be used to drive content-heavy games without having to go to the trouble of messing with deserialization of static assets in a format designed for data.

Bongo Bill
Jan 17, 2012

I rarely find it useful to bother with metatables in Lua. Their main use is making it so that you can make tables have the properties of other data structures while still using table syntax. If your needs are that advanced, I agree you should use something statically typed instead. But tables are powerful enough for most purposes.

Bongo Bill
Jan 17, 2012

PlesantDilemma posted:

Hi thread. I'm a web developer that is interested in making a game as a side project, just a clone of Tetris to start. What javascript/html5 game engine/library is recommended for a new-to-game-dev but not new-to-programming person? There are a lot of options. In my googling around, melonjs seem simple enough for what I want, but I thought I would check in here for other opinions.

I would go with the Elm language's Graphics or WebGL libraries, rather than doing it in raw Javascript, but that's due to a personal preference for static typing, immutability, having a compiler, not using Javascript etc.

Bongo Bill
Jan 17, 2012

I'm not sure I understand the problem, but it seems you could start with determining the minimum and maximum X and Y values among all of your boxes, and whichever has the smallest difference is the axis you should group along.

Bongo Bill
Jan 17, 2012

Globals are bad.

A correctly-implemented singleton incorporates all of the possible benefits of a global, while avoiding the unnecessary drawbacks. The necessary ones are still present, of course.

Singletons make sense to represent resources that correspond one-to-one with the number of processes that you are running. Games, especially small games, have many such resources.

Try it a little something like this. Use it responsibly. I recommend that you not access the singleton at all inside of constructors. Have the singleton instantiate dependencies, but inject those dependencies as arguments to constructors as normal.

code:
// src/Interface/IMySingleton.cs
public interface IMySingleton
{
    void SomeGlobalBehavior();
    int SomeGlobalProperty { get; set; }
    // ...
}

// src/Implementation/MySingleton.cs
public class MySingleton : IMySingleton
{
    public static IMySingleton Singleton
    {
        get { return GetInstance(); }
        set { _Instance = value; }
    }
    
    private static IMySingleton _Instance;

    private static IMySingleton Instance()
    {
        if (_Instance == null)
        {
            _Instance = new MySingleton();
        }

        return _Instance;
    }

    private MySingleton()
    {
        // ...
    }

    public void SomeGlobalBehavior()
    {
        // ...
    }

    // ...
}

// test/Mocks/MyMockSingleton.cs
public class MyMockSingleton : IMySingleton
{
    // ...
}

// test/TestInitializer.cs

// ...
void InitializeTests()
{
    MySingleton.Singleton = new MyMockSingleton();
}

Bongo Bill fucked around with this message at 05:13 on Jul 20, 2016

Adbot
ADBOT LOVES YOU

Bongo Bill
Jan 17, 2012

leper khan posted:

You missed the incredibly important test that instantiation of two of the things returns the same thing instead of two disparate ones. You'd also want to take care in implementation of a singleton that it's thread safe. Basically you should probably avoid writing your own singleton wrapper, as carefully built ones should be available. And if you do need to write one for some reason, use real references not half-put-together fragments from a comedy forum. :catstare:

The accessor already returns a single instance (it's lazily instantiated). But, good catch, I thought I had made the constructor private. It's fixed now.

The point is to demonstrate how it works.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply