Git Product home page Git Product logo

Comments (47)

ffiarpg avatar ffiarpg commented on May 14, 2024 20

I didn't see the godot engine mentioned. It might be worth considering before writing your own.

from blog.

idchlife avatar idchlife commented on May 14, 2024 5

Dear god with generalization of everything and making you know even sub-libraries for your game before you even have working prototype - it's so me. I worked very hard for 3 months for game (browser based), backend and frontend. Everything looked like polished commercial company game. Separate parts, modules, comments, tests etc. Well, I really tried hard, very hard to maintain motivation but at the end I burnt out. It happens. It happens to everyone. In the future games I tend to work with smaller ideas and create tinier and simpler codebases for first prototype to see the light. I hope it will help to finish them.

Looking forward to new posts and engine news from you! ❤️

from blog.

ddouglas87 avatar ddouglas87 commented on May 14, 2024 5

@gotnull Yah, I was rambling a bit much. Passion will do that. I hope I haven't offended.

from blog.

mratsim avatar mratsim commented on May 14, 2024 3

Great write-up !

Since you're familiar with C, you might want to look at the Nim language. It has the syntax of Python, the speed of C and the metaprogramming power of Lisp. Since it compiles to C, C++ or Javascript you can call any C, C++ or JS library in your code.

It's very easy to make a template or a macro that copy-paste part of AB, ABC, ABD, AB* without needing OOP inheritance, generalization, etc.

It is also quite popular among game programmers because you can completely control memory allocation, the GC is optional you can choose to deactivate it globally or for certain objects or choose your implementation or even the max pause allowed.

Here are some game related projects in Nim:

Edit: forgot about

from blog.

vrld avatar vrld commented on May 14, 2024 2

Good writeup. The first two soft lessons feel especially relevant. As for the first hard lesson: maybe half of the nil-issues can be solved by using strict.lua. It won't catch locals or undefined fields in tables, but spelling mistakes will be easily detected. The lua-users wiki also contains a page on that topic.

from blog.

joonazan avatar joonazan commented on May 14, 2024 2

The part about screen capture in-engine makes no sense. You can use NVIDIA Shadowplay to capture all your gameplay. You might have to buy a hard drive for the footage if you don't have a hundred gigs to spare, but that should not matter. A replay system which records game state / player inputs would be a slight improvement over screen capture, but then you run into problems like replay compatibility between game versions.

And please do not build a "trailer system" into your engine. It is called a video editor.

The Jellyfish example is no longer puzzling once you realize that modeling domain objects with programming language objects is a trap. A server is a black box that sends and receives messages, just like an object. But let's say you have an object representing a carrot, and I break it in half. Should the "break" method return one half and transform the object into the other?

If you think about just the data, it is pretty obvious to represent the jellyfish as: jellyfish = { head = {...}, tentacles = [{..}, {..}, {..}] }. Then you can make a function that draws the jellyfish and you can separate drawing the tentacles into their own function if you wish.

You do not give a concrete example about bad abstraction here, but you did give one in chapter 10. The duplicated constructor problem illustrated there could be solved by writing functions that return data instead of thinking in terms of constructors. For example, you can call the function for spawning one kind of enemy and modify the output so that it suits your needs. It's even faster to type out than copying! And Lua should be excellent for doing prototype-based programming.

You can prevent null dereferences by either having a good type system or doing a lot of manual work. For example Haskell has Maybe a = Just a | Nothing for things that may or may not exist. You could do the same in Lua, and it would prevent errors, but it would be frustrating.

It turns out that even with a modest type system, you can apply the Maybe treatment everywhere. Elm, which is basically a subset of Haskell doesn't have runtime errors apart from infinite loops.

from blog.

ddouglas87 avatar ddouglas87 commented on May 14, 2024 2

@SSYGEN

While this seems interesting philosophically I don't understand how it applies to my problems. Could you expand more?

This comes down to the domain of architecture. If you're got an hour checkout this fluff piece that explains the difficulty others face regarding abstraction and generalization: https://www.youtube.com/watch?v=GAFZcYlO5S0 (And if you don't care to watch it, I don't blame you.)

A problem architects have is they draw up the "perfect code base" (or perfect program). Then they give it to a team of engineers (or one engineer, I've been that one), and the engineers look it over and start writing the code. Big deal right?

Well, as time goes on, the code base drifts from the original architected abstraction. This is because when you're down in the trenches you realize there is a better or easier or quicker way to do a thing, so you go do it. This change diverges from the original grand plan.

In many ways this problem is similar to yours, except from a different vantage point. The problem: Creating abstractions before creating the code.

When possible, the code is created first, and then it is abstracted afterwords. This abstraction then seems like an unnecessary step, because then why do it when everything works right? For that, there are multiple good answers to this question. I could rant at you for hours about it, so I'm going to omit all of the reasons but one: If you abstract at the end and take that extra time, every time you do, you will become better at writing and reading code, especially reading and writing libraries and frameworks.

Could you give me examples on this too? I don't understand what you mean exactly.

Sure. Lets say you're in finance (I know, I know, but it's an easy example), and you need to work with currency. You can't use a IEEE floating point type, because under the hood it stores the value in scientific notation, which does have enough rounding errors to make it not a valid use case, especially if this is for a bank or the stock market or similar.

The first solution is using a bignum math library. These have perfect accuracy and have what you call infinite precision. So instead of double current_usd; you've got bignum current_usd;. It's a drop in replacement, so you don't have to change any of your code (hopefully), and it just works. Yay!

But then you notice bignum math is slow. You're doing crazy stock market stuff and it needs to be FAST. So then you end up making a decimal type, which stores numbers with decimals in them like 1.23 in binary under the hood. Now replacing bignum current_usd; with decimal current_usd; and wa-la! Little to no changes to the code base and it is 4 times faster. Nice!

You'll notice here bignum and decimal (as well as float, double, int, ...) are not objects, they're types. Now, you could argue a type is an object, but you could argue everything is an object, so that side steps the point. The point is the way of thinking about it. Are you creating a type of a thing, or are you creating a thing? A thing is just a function / functions with its own state. Basically, globals with functions, then given a class name.

You're already writing objects, even if you're using globals and functions. It's the same thing. The only difference is an object increases code readability, because once you give it a name, you have a single word (and hopefully not a ObjectOfFourWords) that represents it in your head. All of a sudden there is less for you to think about, because the conscious mind relies on words. You're probably already boiling things down in your head to a finite number of words, why not document it in code by turning it into an object? It's a little bit of work to do it at the end but the benefits are enormous.

The big problem is, you don't know what it is going to be called until it is done. You bump into the architecture problem in that video of premature generalization, by trying to name a thing first, not after.

This is why white board problems during interviews are so hard. When you're writing on a white board you usually want to come up with the name first. On an IDE it is easy to change the name later by refactoring.

edit: Oh man, I totally went on a tangent. lol woops. Back to types: Inheritance isn't like object abstraction. If you have 10+ objects that are all similar, the next level of abstraction is creating a module (the name depends on the programming language). There shouldn't be a reason to do this, unless you've got a million similar objects, which you don't, so I wouldn't even consider looking into it. But if you did, you'd still want to do it at the end, after all these objects are already made and solidified.

A type is the type of abstraction for inheritance. Without understanding how to make types and really diving into it, inheritance is always going to come off like a piece of shit. So, imho you should seriously consider creating a type, even as a side project just to explore that process. Once the mentality solidifies, then try creating a 'subtype' or an 'abstract type' (same thing) which is inheritance. This will take some play too. And no, I'm not saying, this is a good idea for your current code base, but instead, once you bump into inheritance in a framework you want to use, or you need to write a framework, or something similar, you now have a path of understanding that will let you get to where you want to go. When the time comes then hopefully it will not be so painful to explore inheritance.

I wouldn't blindly try to create an object, nor a package, nor do inheritance, without conceptually understanding the mental prerequisites behind it away from the act of doing so.

from blog.

joonazan avatar joonazan commented on May 14, 2024 1

@SSYGEN I share your hatred of video editors. AE / Premiere are ok, but expensive. Blender is one option that I'll try the next time I want to edit.

FP error handling

Don't you need to handle the different cases (if the thing is there or if nothing is there) still in your code? If you do then this isn't really that useful since I can just do that on my own. The issue is a way to fix this problem that isn't overly defensive.

There are three kinds of error handling: unhandled errors, badly handled errors and gracefully handled errors. Badly handled errors are arguably worse than a crash, because you don't necessarily notice them.

The functional programming approach is to handle all errors. Madness, right? The upside is that if some piece of code doesn't return an error type, it will do what it is supposed to every time. That is huge for maintainability, as it raises the likelihood that you'll never have to touch a piece of code again.

Handling all the cases by hand would not give you the same guarantee about not crashing. You also usually never unwrap Maybes. Instead, you propagate the error or give a default value. Some examples:

getName : Form -> Maybe Name
getName form =
  Maybe.map2 Name (getField "firstname" form) (getField "lastName" form)
Dict.get n neighbors
|> Maybe.withDefault Set.empty

As you can see, Elm is slightly verbose here. In Haskell or Idris you can avoid the Maybe.map -style functions, but that's not relevant enough to further describe.

From bad to graceful

Actually, there are two kinds of errors. Those that aren't exceptional and those that should never happen. When a player tries to equip an item, but his stats are too low, the error must be handled gracefully. When you index out of bounds, there is no way to recover.

Or so I thought before I tried handling those. I just put some minimal valid values as default values. Now, when a user encountered a bug, things related to the bug usually disintegrated, but that's ok. During development, crashes can be good. User-facing crashes are never good.

That's the baseline. And I found that in many cases I could do way better with very little effort. The next step towards graceful would be to cancel whatever action caused the bug.

I have a lot of time to spend on the functions that can fail, because often when I see a function that can fail I go: "That function should never fail. Can I alter the surroundings so that it doesn't?" and it turns out I can. Doing that is worthwhile, because making one thing never fail usually gets rid of error handling in multiple places.

The abstraction problem

The solution you just mentioned falls into the left side of the AB* image, the one where AB box is inside a transparent * box.

At the core of this problem is the fact that each time we add something new or we change how something behaves, we now have to do these things AGAINST the existing structures. To add or change something we have to always "does it go in AB or AB*?"

I suspect that your problem is that AB and AB* are objects that do not have clear responsibilities. This is pretty much true for any game object, as they mix spawning, behaviour, event handling and drawing. I'm not saying that making that kind of object is wrong, but depending on it with some other code definitely is.

If AB was a function called "uniformRandomLocation", it would be pretty clear that you are not supposed to change it unless it has a bug or your coordinate system somehow changes.

in the first option we end up with an AB that is very complex and has all sorts of switches and flags for its different behaviors

This is almost always bad. Some even teach that all booleans are bad because of this.

I'd say instead of adding flags, split it into pieces or don't use it if it doesn't help as-is. In the example, build a "spawning kit" of useful functions. Similarly, you want to have some common primitives for drawing, so you can for example adjust the line drawing style to taste.

from blog.

Nikaoto avatar Nikaoto commented on May 14, 2024

Good read, always great to read the experiences of fellow lövers :^)

from blog.

dbousamra avatar dbousamra commented on May 14, 2024

Great read :) I also struggled with Unity. I am using libgdx now, and having a better time. I am using your BYTEPATH series as a loose guide to learning gamedev (just implemented in libgdx now)

from blog.

tonetheman avatar tonetheman commented on May 14, 2024

Excellent information and good writeup!

from blog.

a327ex avatar a327ex commented on May 14, 2024

@vrld Thanks for the tip!

@idchlife @Nikaoto @dbousamra @tonetheman Thanks!

@ffiarpg Godot wasn't mentioned because as far as I've researched its developers aren't actively making their own games with it. The main developer seems to have a lot of games in the past, which is good, but if no games are being made currently then it likely suffers from the problems I mentioned in the post in regards to this.

@joonazan

A replay system which records game state / player inputs would be a slight improvement over screen capture, but then you run into problems like replay compatibility between game versions.

And please do not build a "trailer system" into your engine. It is called a video editor.`

My replay system will not be input based and will just record everything, so compatibility problems shouldn't be an issue. And I very much disliked using video editors and I'd rather code my trailers, since it gives me more control. I'll build the trailer system in my engine for this reason.

If you think about just the data, it is pretty obvious to represent the jellyfish as: jellyfish = { head = {...}, tentacles = [{..}, {..}, {..}] }. Then you can make a function that draws the jellyfish and you can separate drawing the tentacles into their own function if you wish.

I was actually thinking about this but I talked myself out of it since the objects from the physics engine are big blobs of code and data, which I thought would make it harder for me to just have everything as data and then a bunch of functions that operate on it like you mentioned. I haven't thought much about if this issue is real or imagined, so this is a way of doing things that I'll definitely explore in the future.

You do not give a concrete example about bad abstraction here, but you did give one in chapter 10.

I don't think you understood my argument regarding abstractions here. The argument applies to every type of abstraction there is, from functions to ECS. The solution you just mentioned falls into the left side of the AB* image, the one where AB box is inside a transparent * box.

For example Haskell has Maybe a = Just a | Nothing for things that may or may not exist. You could do the same in Lua, and it would prevent errors, but it would be frustrating.

Don't you need to handle the different cases (if the thing is there or if nothing is there) still in your code? If you do then this isn't really that useful since I can just do that on my own. The issue is a way to fix this problem that isn't overly defensive.

from blog.

lisardo avatar lisardo commented on May 14, 2024

@SSYGEN Some type systems have nice ways to handle null objects, e. g.:
https://kotlinlang.org/docs/reference/null-safety.html#safe-calls

from blog.

Nicktho avatar Nicktho commented on May 14, 2024

Thanks again @SSYGEN, this repo is becoming a gem of information. I originally started programming with game development in my early teens, although now I work exclusively in the web environment. I was looking around for node/javascript based engines I could use to follow along to your bytepath guide but wasn't satisfied with any of the offerings out there at the moment. I'm so comfortable in JS that i'm not too interested in switching languages just for testing the game development waters again, but nonetheless reading through your content has really benefitted me day to day.

from blog.

a327ex avatar a327ex commented on May 14, 2024

@lisardo Ah, thanks. That syntax is really nice and would be way less intrusive to use. I think that would solve my problems with this almost completely.

@Nicktho Thanks!

from blog.

chartinger avatar chartinger commented on May 14, 2024

If you have the time i would recommend writing your own engine anyway - even if you do not use it, you learn a lot of things and get a better understanding why and how existing engines are the way they are and what they tried to solve.

I still prefer libGDX for my projects (as a hobby, game jams) with a custom mini "framework / engine" on top.

from blog.

vadi2 avatar vadi2 commented on May 14, 2024

Did you use Luacheck during development? It is a godsend for proofing errors.

from blog.

ddouglas87 avatar ddouglas87 commented on May 14, 2024

@SSYGEN Are you making an argument for procedural programming over OOP for small games?

Over generalization is a real issue, and over abstraction can make reading code difficult. Also, you probably already know this, but procedural programming is much better as a 'get up and go' paradigm. However, I wonder if this difficulty with generalization comes from a lack of bottom up programming with passive abstractions.

Rigid abstraction can be a common difficulty in top down programming (usually leaving code bases decoupled from their original architected abstraction), where bottom up programming tends to not suffer from this anywhere as much. For example, instead of making objects from the get go, making a handful of units (usually functions), and then down the road bundling them together into a common abstraction can work out better. This way an abstraction is only created when it is beneficial or necessary, building up, not down.

from blog.

ThaisRobba avatar ThaisRobba commented on May 14, 2024

@SSYGEN really nice write up - and congratulations on the game release!

You might want to take a look at Amulet (http://www.amulet.xyz) - it is a small, pragmatic game engine with built-in support for exporting to multiple targets (including HTML) and the creator, Ian McLarty, develops his games with it.

It is very "batteries included" and warrants a look - even if only for inspiration :-)

from blog.

jaythomas avatar jaythomas commented on May 14, 2024

Premature Generalization is a case of making your code DRY before you finish fleshing out the pieces and it's not an issue specific to just game development. Donald Knuth said premature optimization is the root of all evil.

from blog.

mattiasgustavsson avatar mattiasgustavsson commented on May 14, 2024

I agree with a lot of what you're saying. I also think that having your own engine can make the process more enjoyable too - no fighting a third party tool you don't know or control. If you've made your own engine, you know exactly what everything is.

The "timer" system you describe - I have one very much like it (but in C++ so using lambdas and a bit of templates), and it really is a very very powerful tool - makes many things so much easier.

When I wrote my engine, I decided to build many of the low level systems in stand-alone C or C++ modules, and then just have a high level layer to tie everything together. My intention was that the low level modules would be useful for others making their own engine - maybe as a starting point or intermediate solution.

from blog.

a327ex avatar a327ex commented on May 14, 2024

@vadi2 I didn't, but thanks for the tip, I'll check it out.

@ddouglas87 I've been thinking about that a lot and I wanted to try coding that way more but I seem to always default to objects when it comes to entities because it seems to make more sense.

@mratsim Thanks for the post. I've checked Nim multiple times before and I'm really interested in it but it's probably something I'll leave for the future to seriously consider. I don't like using tech that hasn't been around for a while at least with a number of proven projects.

@mattiasgustavsson I've seen your single file libs repo before. I really like that way of doing things in the C/C++ gamedev community and I'll also use some of those libraries in my engine when possible. Thanks! ^^

from blog.

ddouglas87 avatar ddouglas87 commented on May 14, 2024

@SSYGEN You may or may not already know this, but if you abstract procedural paradigm code as one of the later steps (maybe even last step) then you will see and learn new ways of creating abstractions that will not step on your toes.

Refactoring is a game with a different goal.

And inheritance: it's not taught properly in any books I've read. Inheritance is about creating subtypes. It's type theory: you're creating a type of a thing, instead of a thing. It's not about reducing code duplication but instead creating new types of things, or using someone else's types.

So for that, I gotta ask, "Have you tried making any types before, instead of just objects?"

from blog.

a327ex avatar a327ex commented on May 14, 2024

@ddouglas87

So for that, I gotta ask, "Have you tried making any types before, instead of just objects?"

While this seems interesting philosophically I don't understand how it applies to my problems. Could you expand more?

You may or may not already know this, but if you abstract procedural paradigm code as one of the later steps (maybe even last step) then you will see and learn new ways of creating abstractions that will not step on your toes.

Could you give me examples on this too? I don't understand what you mean exactly.

from blog.

joakim-noah avatar joakim-noah commented on May 14, 2024

Don't just stick with C/C++, compare newer languages like the D programming language, someone mentioned Nim earlier. D even has some Lua wrappers you can use.

from blog.

gotnull avatar gotnull commented on May 14, 2024

@ddouglas87 You must be fun at parties.

from blog.

dbriemann avatar dbriemann commented on May 14, 2024

Great read. I am currently undecided between using a framework/engine/library or writing my own. I have worked with Love2d and encountered similar problems as you: building and deploying to different platforms, adding in-app purchase or ads to e.g. an android game etc.

Since you seem to be a C coder have you had a look at raylib(C library, also has Lua bindings)?

You have complained about the myriad of ways that Love/Lua allow you to structure code / write the game. Have you thought about using Go? It enforces very clear code. There is also the ebiten game framework which is very promising but so far does not support custom shaders (which is holding me back). The developer also has created and released at least two mobile games with it AFAIK.

from blog.

paxer avatar paxer commented on May 14, 2024

@SSYGEN what’s your thoughts about Defold https://www.defold.com ? It is Lua, King (the engine developer) use it for their own games and they have a really nice core concept of “message passing” https://www.defold.com/manuals/message-passing/ between objects similar to Erlang which eliminate many null issue cases and decouple objects from each other.

from blog.

flamendless avatar flamendless commented on May 14, 2024

@paxer alot of devs dont want to use it since it's not open source, and it's made by king (which is like people not liking windows because of, well, Microsoft). Another most hated feature of it is that you can't work on it if youre offline

from blog.

paxer avatar paxer commented on May 14, 2024

@flamendless with Defold, you have to be online when you create a new project, but after that you can work offline. They are planning to remove this requirement in the future release. Actually in the new editor you can work offline, but with the 1.x it is still an issue

from blog.

a327ex avatar a327ex commented on May 14, 2024

@paxer I've looked into it and I really like a lot of what they're doing, but not having the code is a deal breaker unfortunately. I'm going to steal a few of their ideas on how to do certain things because they're really good, however.

As for message passing I don't think that's a good idea for general gameplay coding. It just seems very bureaucratic and while it would help to solve the nil issues I don't think I wanna solve them in a way that makes coding the game more painful than it needs to be.

from blog.

flamendless avatar flamendless commented on May 14, 2024

@paxer really? Then that's awesome!

What i like about defold is that it's very easy to export for android, also, a lot of useful plugins!

from blog.

flamendless avatar flamendless commented on May 14, 2024

@paxer actually, can you give me the link about their plan to remove the online requirement for creating a project?

from blog.

paxer avatar paxer commented on May 14, 2024

@flamendless checkout this thread https://forum.defold.com/t/how-can-i-work-offline-as-defold-new-project-has-to-be-created-online/1937/9

from blog.

a327ex avatar a327ex commented on May 14, 2024

An example of the kind of code that I'm talking about in the "Soft Lessons" part of the article https://github.com/NoelFB/Celeste/blob/master/Source/Player.cs

from blog.

ehnba avatar ehnba commented on May 14, 2024

Sweet article!

I still do disagree with generalization though.
Although I do agree that organically coding is better for early projects or small teams, I still see the need for reusuablity.

I feel that the biggest hurdle is the jump in paradigm - ECS, for example is notoriously inconsistent in implementation and is a lot harder to learn than general OOP.

Once you get past the original hurdle, it's a lot easier than you'd be lead to believe to code, I think.
Something I've been doing in some projects is that the player is just a variable container and all the actual state is in separate state machines (which is pretty common).

Not everything needs to be generalized, though.
Although the Celeste code you linked isn't ideal (far from it), it's still usable and functional, which is a lot more important than clean code, like you said.

Also, side note about Unity from someone who uses it a lot:

Although I would agree that it seems like the developers have a huge disconnect from the community a lot of times, I feel like it's gotten better in the past year.

Lots of not-broken features have been introduced, and open-sourced, like the SRP, Shader Graph, ECS, and Input System for active feedback and contribution, and acquisition of community features to integrate into the full engine, like ProBuilder.

It only appealing to newcomers part is simply not true - people from Nintendo to Blizzard or the developer of Subnautica use it, so that's gotta mean something, right?

Anyway, rant over, awesome article, and good luck on your engine!

from blog.

ChengCat avatar ChengCat commented on May 14, 2024

Thanks for sharing your experiences. I am also in progress of making a switch away from LOVE. I have been introducing too many C library components into my game, and at one point it seems to me that I only need LOVE to receive input events, which could be easily replaced by a Lua binding to GLFW or SDL.

I have read LOVE's source code, and it can be seen as a set of Lua modules written in C++. The whole game is actually driven from Lua side. It's not hard to build your own engine with the help of a set of third-party C libraries and LuaJIT FFI.

I am deciding to take a step further, and try a Lisp language in place of Lua. I am concerned with the status of LuaJIT, and I am feeling that I am more productive with a Lisp language. My biggest concern so far is the GC pause, and I think I can properly evaluate the situation only after making some progress.

from blog.

meghprkh avatar meghprkh commented on May 14, 2024

Just an aside, I just realized Github issues is a really good way to blog, with comments and reactions 😅 Only lacking thing IMO is analytics

from blog.

notverymoe avatar notverymoe commented on May 14, 2024

Really interesting write-up, thanks for putting it out there! I definitely understand a lot of what you're talking about, particularly regarding overgeneralization.

Anyway, hope your engine development is speedy!

P.S. Never thought about using github for blog entries, might look at doing that. The formatting and reacts are really useful!

from blog.

kravchik avatar kravchik commented on May 14, 2024

It's not just that the contexts of indies and teams are different. For the team - a complex structured and abstruse-hierarchical code - the same evil as for indies. The fact is that the role of inheritance is hypertrophied in virtually all textbooks, and dislodges the composition and copy-paste. So I'd focus on this priority: first copy-paste, then re-use via function or composition, and only in extreme, reinforced-concrete-proven case - use a hierarchy.
I can also say that in fact, there is not much difference between an indie and a team. Indie has sections of code that will be reused many times and will be polished "like by adults" - all sorts of core-components. And the teams have sections of code that need to be "just written" and not rewritten - because tomorrow the client can ask something different. Just the ratio of one and the other in different projects may differ.

Yes, with Unity, sadness comes out. They have already created a gold mine, their own market, from which they collect their rabid interest. So they should focus on this - a stable engine (and not with features). Ie, IMHO, it's a bad practice - being the masters of the market - and trying to compete with sellers (create services, include Assets in the main engine, add features), instead of improving the conditions of the market itself (increasing engine stability, stimulating sellers/buyers of Assets).
And they should add more features to the market itself, different licenses, subscriptions - so that users could not only buy one-time but also sponsor, as on Patreon. This I proceed from my experience. So I released the Asset, it is not needed by everyone, but for whom it is needed - it saves hundreds of hours of animators or is generally key for the game. And, it turns out that sales do not cover my work on the asset, but those for whom it is important - are willing to pay for updates / monthly, but can not.

About trailers. I suffered until I understood two things.
The first is to find a convenient editor. Set a task - and try to solve in different editors. The majority rejected at the stage of loading, with two or three in principle, something can be done, and the only one you fall in love with, and, finally, you can do business :) (I stopped with kdenlive).
The second. Just like you. I listen to a track and imagine what will happen on the screen. And then everything is simple - cut under the track, under the beat, under the change of the melody.
By the way, in my engine (in Java) - I made a recording of sound and video to get smooth videos. So I can compose that kind of videos where you can see the smoothness and those 60 frames. In Unity, this could be done only without sound and with a non-real-time rendering.

from blog.

Apollo144 avatar Apollo144 commented on May 14, 2024

@SSYGEN take a look at Gideros SDK, it truly is a hidden treasure.
It's open source, no marketing blah blah blah, you can join the team if you want.
It has:

  • instant on-device testing
  • unique "fake threads" system
    (if you want you can program a mobile device like you used to program the Commodore 64)
  • html5&Facebook instant games support
  • and many more

from blog.

egordorichev avatar egordorichev commented on May 14, 2024

@dbousamra the issue with LibGDX, is sadly, no consoles support what so ever. In anything else, its an awesome engine!

from blog.

srodrigo avatar srodrigo commented on May 14, 2024

Don't just stick with C/C++, compare newer languages like the D programming language, someone mentioned Nim earlier. D even has some Lua wrappers you can use.

What about Rust? I know very little about Nim, but I haven't seen any big projects using it, and no-one uses D (its creator doesn't count). Rust is used for major projects such as Firefox and NPM. Whereas it's still not very used in game dev, I would rather have a look at it instead of marginal languages.

from blog.

srodrigo avatar srodrigo commented on May 14, 2024

I'm going to read the links provided about problems with Unity. I was almost decided to use MonoGame (I don't mind C# :) and actually probably makes you more productive than C++), but the Unity roadmap for next year looks quite good. I'm afraid of hitting roadblocks with Unity though, that's why I'd prefer something less intrusive, and MonoGame is the only serious framework, baked with game hits.

Honestly, even if I would love to build my own tech for the complete control it would give, that would mean not focusing on making games. This is a trap, and you will end up spending all your energy and time on the engine, and probably not ship any games. Also, I don't like C++, and Rust (the only serious alternative, someday) is still too young for game dev. So unfortunately (or not), I'll 99% sure go for MonoGame.

from blog.

JoaoBaptMG avatar JoaoBaptMG commented on May 14, 2024

The three soft lessons were like a blow to my chest. I do not have a lot to add, but it seems like everything I took years to learn standalone and while in university simply lost all their value. I could argue with you as long as I wanted, but I saw these consequences becoming real in one of the projects I am still struggling to continue. Anyway, I will take that to heart when I (try to) make my next games (sadly, that will leave me with not a lot of "decent" code I could show to business to hire me).

from blog.

suaviant avatar suaviant commented on May 14, 2024

I stumbled upon this just now. Great write-up. Thanks for this. I agree with a lot of it and you have said much that goes unsaid (so far as I know). As a game dev, getting it done and done well is the primary concern.

And yes, I found a problem with a Unity module and took it to the forums and the resulting exchange was downright meme-able. In the end, no solution.

I will be recommending to my company we move on from Unity one or two projects down the line (we do small scale) and onto something open source. Personally, I never want to touch it again.

from blog.

anthonyk1225 avatar anthonyk1225 commented on May 14, 2024

Since reading this last week, I've thought of what you wrote in the Premature Generalization section at least 10 times. I feel like a weight has been lifted off my shoulders. Being DRY is good, but getting sh*t done is better. Thanks for the thought-provoking post.

from blog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.