Status
Not open for further replies.

FLCL

Member
Oct 27, 2017
1,548
So when you design an asset, you are not saying "I want this asset to be N pixels wide", instead you are saying "I want this asset to take up a certain percentage of screen space". Therefore if you decide your asset needs to be 10% of the visible width, and your "native resolution" for the game is 100px, then your asset needs to be 10px wide.
Thank you! Definetly understand most of it now, I think. I had already looked up some of it and have a pixel perfect camera in Unity set to 640x360 reference resolution and 32 PPU. But I didn't think about the quoted part when creating my assets so they didn't take up quite as much of the screen as I planned to. But now I know how I can think about it while creating the assets.
 
Oct 26, 2017
4,017
Thank you! Definetly understand most of it now, I think. I had already looked up some of it and have a pixel perfect camera in Unity set to 640x360 reference resolution and 32 PPU. But I didn't think about the quoted part when creating my assets so they didn't take up quite as much of the screen as I planned to. But now I know how I can think about it while creating the assets.

Cool! Glad that helps!

Just as an aside, the PPU doesn't really matter in relation to rendering (and scaling), its more about positioning for your actual assets within a scene and can relate to physics as well. It doesn't have an effect on the drawing process, but that said it does come into play when you try to clamp your camera to a pixel-perfect location (Preventing pixel jitter).

What you use for a PPU is totally up to you. 32, 64 etc can be useful if it matches with a tilemap or similar and you want to easily be able to figure out co-ordinates based on how many tiles are places.. I think my game is at 100ppu. Just be aware that it can have an effect on physics calculations if your game makes use of physics.
 

Qwark

Member
Oct 27, 2017
8,169
I don't know of any videos explaining it, but I can try to explain it a little better.

Let's think about just working in one dimension to start with We'll talk about X. The same principle applies to both the X and Y axis, but trying to consider them both at the same time might be a little confusing. And, for simplicity's sake we will use easy to divide/visualise numbers, not that these would be the numbers that you would actually use in-game.

So, you're designing a level in your game, and you decide that regardless of the screen resolution that the game is being played at you want the same visible area to be displayed. That means that if someone is playing at a resolution of "100 pixels" and another person is playing at a resolution of "200 pixels", their game view should be identical, albeit stretched to fit the resolution.

The person playing at the 200px resolution would not be able to see any additional details to the left/right, compared to the 100px player.

With me so far?

So when you design an asset, you are not saying "I want this asset to be N pixels wide", instead you are saying "I want this asset to take up a certain percentage of screen space". Therefore if you decide your asset needs to be 10% of the visible width, and your "native resolution" for the game is 100px, then your asset needs to be 10px wide.

So what happens when the 200px player comes along? Obviously 10px is not 10% of 200, it's 5%, so, in order to prevent your assets from looking smaller on the 200px resolution, we instead (In the game, via the camera) draw the game scene at the native resolution (100px) and then scale that up by a factor of 2! That way your 10px asset becomes drawn over 20px, which maintains the same percentage of screen width.

This scaling factor is done based on the resolution (And should be handled automatically by the camera. This is normally done via "pixel perfect" scaling or similar) So if the target resolution was 300px, the scale factor would be 3 and so on.

What you need to decide as the designer is what the native resolution of your game is, which gives you the concept of how "big" your assets will be in-game.

The reason we say you need to be careful when deciding a native resolution, is because when working with a pixel art game you want to choose something where it can scale to other resolutions using only an integer scaling factor (1,2,3 etc.) The reason for this is because when you do so, your scaled pixel-art is guaranteed to "fit" the pixels of the target resolution. For example:

If you have pixels draw at coordinates 0->3, and you need to scale this by a factor of 2, the output is that pixels are draw at coordinates 0->6. Those coordinates relate to actual physical pixels on a monitor.

However, if you took 0->3 and attempted to scale it by a factor of 1.5 you would get coordinates of: (0, 1.5, 3, 4.5) This is bad because those decimal coordinates do not relate to an actual physical pixel on the monitor. GPU doesn't know exactly how to render that, so it will make a best-fit (Which is normally rounding). That rounding means that sometimes the pixel will be drawn only on the integer part (e.g at pixel 1) and sometimes it will render in both pixel 1 and pixel 2. THAT gives you pixel jitter.

(It is also important to note that if the camera is positioned in such a way where it is not clamped to a "pixel relative" value, you can also get pixel jitter due to the offset, but thats a story for another time)

EDIT:

I found a link that explains the issue quite well with visual examples. This is actually the exact problem I had (Started at 720 native, tried to scale up to 1080)
gamedev.stackexchange.com

Scaling my pixel art platformer from 720p to 1080p

I'm developing a pixel art 2D platformer for PC and smartphone, but I'm stuck on a technical issue. I chose to have a 32x32 tile resolution, and a 64x64 character sprite resolution. The levels are

Luckily I found another way of fixing it after some heavy googling. Still not ideal but it works to the degree that people might not notice if they weren't originally aware haha!
Sorry, I just have some clarifications to ask regarding this and the original question (thanks FLCL, I had a lot of the same questions). I get the concept of designing a sprite to take up 10% of the screen real estate or whatever. But my question is around sprites that don't necessarily fit in a perfect 32x32 box. Say, I want a bigger sprite so I work in 64x64, but 64 doesn't perfectly divide into 360 (though, 32 also doesn't divide into 360 so maybe this isn't even a concern). Is that going to cause jitter or will it not because it's placed on an authored resolution of 360x640 and THAT'S what is scaled, everything included on there and not the individual sprites?

Does that question make sense? I'm just worried about working with sprites that don't scale perfectly to 360x640.
 
Oct 26, 2017
4,017
Sorry, I just have some clarifications to ask regarding this and the original question (thanks FLCL, I had a lot of the same questions). I get the concept of designing a sprite to take up 10% of the screen real estate or whatever. But my question is around sprites that don't necessarily fit in a perfect 32x32 box. Say, I want a bigger sprite so I work in 64x64, but 64 doesn't perfectly divide into 360 (though, 32 also doesn't divide into 360 so maybe this isn't even a concern). Is that going to cause jitter or will it not because it's placed on an authored resolution of 360x640 and THAT'S what is scaled, everything included on there and not the individual sprites?

Does that question make sense? I'm just worried about working with sprites that don't scale perfectly to 360x640.

That's right! The issue doesn't arise from the resolution or dimensions of your assets, it comes from the native resolution of the game.

So in your example, (again, only talking about width for simplicity but its the same for height too) your sprite will occupy 64 pixels of the 360 pixels available on your game's screen. This means the sprite will take up approximately 17.8% of your screen width.

Decimal numbers in the percentage are absolutely fine! As (at native res) your sprite is still only being drawn on the 64 pixels that you authored it on, so there isn't an issue with pixel jitter. The decimal in the percentage is just "how it is". It's an abstract concept to express how much real-estate is being taken up, but isn't being used in any calculations so don't worry about it!.

I'll walk you through what happens in the next stage where you scale your game up to 720x1280 resolution.

720p is double 360p, so it means that all you sprites will be scaled by a factor of two. This means that your 64 pixel sprite becomes a 128 pixel sprite! All the pixels in your original asset are simply just "doubled up" so they scale perfectly and you don't get any jitter! When we go up to 1080p, our scale factor is 3 (1080/360), so the sprite goes from 64 to 192 pixels. This time, "tripled up" so you're fine!

I'm sure you've got it by now, but I'll just walk you through the bad case (As in, the mistake I made) too.

I authored my sprites to be used on a 720p native resolution, however, when scaling up to 1080p the scale factor was 1.5! That meant that my sprites could not be uniformly scaled into the target resolution. So that means that in some of the pixels in my sprite were doubled up, and others were left the same as the native resolution. The pixels chosen for the doubling are based on their position on the screen relative to the camera, so as they move around the pixels selected for doubling change, which is what leads to the pixel jitter.

And in case anyone is wondering I fixed it by use of a shader I found that esentially uses a combination of nearest neighbor and bilinear filtering to get a "best of both worlds". It's not perfect, but it looks pretty good!

Hope that helps and let me know if you've got any other questions!
 

Qwark

Member
Oct 27, 2017
8,169
That's right! The issue doesn't arise from the resolution or dimensions of your assets, it comes from the native resolution of the game.

So in your example, (again, only talking about width for simplicity but its the same for height too) your sprite will occupy 64 pixels of the 360 pixels available on your game's screen. This means the sprite will take up approximately 17.8% of your screen width.

Decimal numbers in the percentage are absolutely fine! As (at native res) your sprite is still only being drawn on the 64 pixels that you authored it on, so there isn't an issue with pixel jitter. The decimal in the percentage is just "how it is". It's an abstract concept to express how much real-estate is being taken up, but isn't being used in any calculations so don't worry about it!.

I'll walk you through what happens in the next stage where you scale your game up to 720x1280 resolution.

720p is double 360p, so it means that all you sprites will be scaled by a factor of two. This means that your 64 pixel sprite becomes a 128 pixel sprite! All the pixels in your original asset are simply just "doubled up" so they scale perfectly and you don't get any jitter! When we go up to 1080p, our scale factor is 3 (1080/360), so the sprite goes from 64 to 192 pixels. This time, "tripled up" so you're fine!

I'm sure you've got it by now, but I'll just walk you through the bad case (As in, the mistake I made) too.

I authored my sprites to be used on a 720p native resolution, however, when scaling up to 1080p the scale factor was 1.5! That meant that my sprites could not be uniformly scaled into the target resolution. So that means that in some of the pixels in my sprite were doubled up, and others were left the same as the native resolution. The pixels chosen for the doubling are based on their position on the screen relative to the camera, so as they move around the pixels selected for doubling change, which is what leads to the pixel jitter.

And in case anyone is wondering I fixed it by use of a shader I found that esentially uses a combination of nearest neighbor and bilinear filtering to get a "best of both worlds". It's not perfect, but it looks pretty good!

Hope that helps and let me know if you've got any other questions!
Makes perfect sense now, thank you for the thorough explanation! Now time to rework everything in 640x360. Hopefully it doesn't break too much stuff.
 

Qwark

Member
Oct 27, 2017
8,169
Bit of a vague question, but what's a good length for say an idle animation? I've been doing 3 second (32 frame) animations but things seem way too fast, definitely going to need to add some frames to slow things down a bit.
 

Squirrel09

Member
Nov 4, 2017
1,635
Hey all, my new years resolution for 2020 was to build a new android game/app each month. So, each month I build something new each month! In may I decided to create an Idle game! It's called "Ball Factory" and you can find it for Android here!

I decided to make this after enjoying "Bee Factory" and "Idle Egg Tycoon". but finding the need for their monetization a bit too extreme and intrusive. Now, don't get me wrong... My app isn't the next best clicker.. far from it. But I'm proud of what I've accomplished in a month, and overcoming the challenges from creating something from scratch.

Some particular tough challenges

Creating a number converter so you don't see 1,464,723,125,234. Because that's uglier that 1.46 T.

Getting the progression rate set to feel fair, challenging, and rewarding was tough. And I hope I got it right :D.

Make scripts that were (near) infinitely scale-able. Part of the challenge of making a game in a month is relying on reusable Assets. Creating a system where each ball is a color, all I have to do is Add a color to a list and Wala! Everything is created in script to add the stage.

Some things I wish I had time to do better

Progression. While I think the progression is as good as I could get it. It was only play tested by friends/family. I'm sure if I had time for a public beta I would have received more feed back to better fine tune the systems.

All the balls are just colors. This is fine, but it would be more exciting if I had time to create a bunch of individual sprites like beach balls, pool balls, sports balls, faces, random round objects. If I gave myself 2-3 months/game this would have been much more reasonable to do.

Notes on Monetization There are ads and IAP for this. You can watch an Ad to get Gems, and use those gems to increase different stats (Speed, profit, production, creation time). or the IAP to buy Gems.

These Monetization options were added at the end AFTER I finalized progression. So, they are not needed to progress. But are there if you want.
 

jarekx

Member
Oct 25, 2017
625
So i was thinking about a game that used the active reload mechanic as the means of attack. Basically, you would have zones on it that ranged from critical, to miss, and possibly to enemy hits you. You and the enemy would basically select an action at the beginning of the turn and it would change this bar that has all those different outcomes on it and then you would then try to stop it on an outcome that favors you. The main thing that sounds weird to me is that you wouldn't get hit if you never messed up. Which I guess is true of a lot of games but the simplified nature of this just kinda makes that seem a lot easier to achieve. I also thought of having an enemy slider run at the same time and when you clicked to stop they both stopped...so you were just trying to stop yours in an attack portion and theirs in a miss, for example.

Idk, maybe i'll try and put it together and see how i feel about it.
 

PsionBolt

Member
Oct 27, 2017
1,311
So i was thinking about a game that used the active reload mechanic as the means of attack. Basically, you would have zones on it that ranged from critical, to miss, and possibly to enemy hits you. You and the enemy would basically select an action at the beginning of the turn and it would change this bar that has all those different outcomes on it and then you would then try to stop it on an outcome that favors you. The main thing that sounds weird to me is that you wouldn't get hit if you never messed up. Which I guess is true of a lot of games but the simplified nature of this just kinda makes that seem a lot easier to achieve. I also thought of having an enemy slider run at the same time and when you clicked to stop they both stopped...so you were just trying to stop yours in an attack portion and theirs in a miss, for example.

Idk, maybe i'll try and put it together and see how i feel about it.
I'm a pretty big fan of those sorts of combat systems. Usually they decouple your attacks and the enemy's; as in, the way the enemy attacks (and thus, whether you get hit or not) isn't the same bar system you use -- I'm thinking of Resident Evil Gaiden and Undertale / Delta Rune here, mostly, which give the enemy attacks real-time elements. But the idea of it being strictly turn-based and having both you and the enemy on a bar system is something I don't think I've ever played. It could be novel and interesting for sure.
 

jarekx

Member
Oct 25, 2017
625
I'm a pretty big fan of those sorts of combat systems. Usually they decouple your attacks and the enemy's; as in, the way the enemy attacks (and thus, whether you get hit or not) isn't the same bar system you use -- I'm thinking of Resident Evil Gaiden and Undertale / Delta Rune here, mostly, which give the enemy attacks real-time elements. But the idea of it being strictly turn-based and having both you and the enemy on a bar system is something I don't think I've ever played. It could be novel and interesting for sure.

Ya, Undertale and Paper Mario were what came to mind when it popped in my head. I haven't really seen one where attack and defense are kind of rolled into one. I have a few ideas with enemies maybe having their marker teleport, or speed up and slow down, or maybe an enemy that puts a strict timer on how long you can wait for you have to choose.

Originally, I was thinking of how I can make a rock, paper, scissors type system work without it being entirely dependent on choosing the correct action vs an enemy. So I had the idea to use that active reload / timer, and if you choose correct you would have an easier time in that portion, whether it be an increased dead zone for a success, slower movement, or something in between. It sounds interesting, but I couldn't really think of a way that enemies would benefit from you choosing incorrectly..other than you might miss if it's an attack.

EDIT:
JwmMM0D.png

Just figured I'd throw this one in there too. It what I've been working on recently. Basically, you are a god/diety guiding and helping a party of adventurers. Basically, when you hit end all enemies in the line would attack first from front to back ( though I was planning on adding a trait that allowed some to attack in the opposite order), and then your party acted in the same order. I had a few modifiers in it like haste that allowed you to go first whether you were an enemy or ally unit, attacks that pushed you back or others back, stuff like that. You helped by using divine powers to hurt enemies or buff allies before the turn started, as well as move allies around to get them in an optimal position to either soak up or avoid damage. I just really ran out of ideas for how I could customize units and godly powers. Since, a units attack was set all I could really modify for them was how much damage they dealt, how much hp they had, and whether they started battle with some of those effects. Just did not have enough variety for me.
 
Last edited:

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
i'm trying to conceptualise a lock-on system to distract from having to conceptualise a pick-up-and-throw items system to distract from conceptualising a weapons system to distract from having to redo my hit reaction system to distract from having to code AI to distract from having to do animations...
 

Weltall Zero

Game Developer
Banned
Oct 26, 2017
19,343
Madrid
Porting to Switch is going reasonably smooth. I stumbled a couple of times on things that were ultimately my own fault, but I think I should have something to show tomorrow.

i'm trying to conceptualise a lock-on system to distract from having to conceptualise a pick-up-and-throw items system to distract from conceptualising a weapons system to distract from having to redo my hit reaction system to distract from having to code AI to distract from having to do animations...

[Procrast[inception]]. I do that all the damn time. One of the reasons why regularly sending prototypes / vertical slices / alphas to friends and families is so important; it forces me to cut the bullshit and get something finished.

It sounds like you're doing all of that to distract from having to downscope the hell out of your game, too... :)
 

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
oh no please this is already the downscoped version where i just want to figure out left to right fight three dudes and then fight a boss

but it turns out

to do that in a combat focused game

you need to build the entire combat part of it

if i downscoped any further i wouldn't be making the game i want to make
 

Weltall Zero

Game Developer
Banned
Oct 26, 2017
19,343
Madrid
oh no please this is already the downscoped version where i just want to figure out left to right fight three dudes and then fight a boss

but it turns out

to do that in a combat focused game

you need to build the entire combat part of it

if i downscoped any further i wouldn't be making the game i want to make

I didn't mean downscoping as in "this is all that the game is ever going to be", I mean as in defining what the first prototype / minimum viable product is going to be. You can start with a game with no weapons / items / throws, and build from there. I find that far less stressing and easier to wrap my head around and finish than having half a dozen systems in varying states of completeness. Try to force yourself to complete the simplest imaginable version of your game, as quickly as possible, then build upon that.

I know I'm not telling you anything you don't know, and that this is pretty much the entire point of your post, hahah. It's just too easy to get caught in a loop of chasing after the next shiny thing, which usually leads to eventually abandoning it all when there's too many old, unappealing, unfinished systems gathering cobwebs.
 

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
haha, you're right though. i should really get to the enemies-actually-do-something phase before i start faffing around with item throwing
 

FLCL

Member
Oct 27, 2017
1,548
I went down a rabbit hole yesterday. I implemented a dodge roll but was able to change direction during the dodge which is not what I wanted so I started to look into states. Started to implement a basic state pattern with enum and switch case. Simple, fast and it made my code a bit cleaner but I could tell it was going to get messy down the road so I looked into it further. Now I have different classes for each state and so far it's working. Not quite sure if I implemented it correctly and each person doing a tutorial on it has their own version so it took forever to wrap my head around it.

I do have a question though. When doing states how do I make sure I stay in a certain state for the intended duration? For example if I start an attack state I want to stay there until the attack is finished to be able to walk, maybe cancel the animation at X point with a new attack or dodge etc. I solved it by setting a variabel to X seconds and then check if those seconds has passed and then if true move on to next state. Is that a decent way to handle it or is there a better method? Also when checking time like that is Time.time or Time.deltatime prefered? Since the attack is dependent on an animation and thus frames it should be deltatime, or?

Edit: Ok so... Maybe use Coroutines and yield return new waitforseconds...? That means I have to rebuild the state solution a bit though because it does not support coroutines right now.
 
Last edited:

Weltall Zero

Game Developer
Banned
Oct 26, 2017
19,343
Madrid
I went down a rabbit hole yesterday. I implemented a dodge roll but was able to change direction during the dodge which is not what I wanted so I started to look into states. Started to implement a basic state pattern with enum and switch case. Simple, fast and it made my code a bit cleaner but I could tell it was going to get messy down the road so I looked into it further. Now I have different classes for each state and so far it's working. Not quite sure if I implemented it correctly and each person doing a tutorial on it has their own version so it took forever to wrap my head around it.

I do have a question though. When doing states how do I make sure I stay in a certain state for the intended duration? For example if I start an attack state I want to stay there until the attack is finished to be able to walk, maybe cancel the animation at X point with a new attack or dodge etc. I solved it by setting a variabel to X seconds and then check if those seconds has passed and then if true move on to next state. Is that a decent way to handle it or is there a better method? Also when checking time like that is Time.time or Time.deltatime prefered? Since the attack is dependent on an animation and thus frames it should be deltatime, or?

Edit: Ok so... Maybe use Coroutines and yield return new waitforseconds...? That means I have to rebuild the state solution a bit though because it does not support coroutines right now.

This is an excellent question because syncing logical / code states with Unity's animation system tends to be a headache. One of the ways I did it is by using a not-very-publicised feature that allows you to add scripts to the animation states themselves, with functions that get called when the character enters or exits a given animation state.

If you make a class like this:

Code:
using UnityEngine;

public class MyAnimationState : StateMachineBehaviour {

    override
    public void OnStateEnter (Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
        base.OnStateEnter (animator, stateInfo, layerIndex);
        // Do stuff.
    }

    override
    public void OnStateExit (Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
        base.OnStateExit (animator, stateInfo, layerIndex);
        // Do stuff.
    }
}

Then add it to any animation state, these functions will be called when the animator enters and exits that state. You can easily use it to lock your character out of performing any other action or moving.
 

TeaberryShark

Member
Feb 8, 2019
853
So I'm working with animator state behaviours right now and I have a question if anyone can help. I have an NPC, the NPC has an AI script that controls things like animator parameters and etc. He has a baseFSM class with a few variables (reference to the player etc) that all of his state behaviours inherit from. I want to give the NPS a patrol behaviour and I'm having some issue.

Right now in his patrolbehaviour script on awake it looks for an array of objects tagged "waypoint" then he moves through the circuit. This is fine and it works but it isn't ideal because any instances of the npc I put in a level will all share the same waypoint circuit. My thinking is, have a child game object on the npc that contains an array of waypoints specific to that npc, get the reference in the AI script and pass it to the animator behaviour script...

For some reason I'm having the damnedest time with passing a reference to the array into the animator behaviour scripts. I'm sure I'm making it harder than it has to be... ugh. Anyone know how i could do this (create original reference to Transform[ ] waypoints on the NPC AI script ---> reference said array in NPS Animator State base script ----> look up the [ ] in the PatrolBehaviour script).

SOLVED: my dumb self forgot to call the function I made to populate the array :/ crisis averted!
 
Last edited:

CptDrunkBear

Member
Jan 15, 2019
62
I'm really excited to show this off - my game's gone to closed beta! I'm now play- and bug-testing it, and I'm set to release really soon.

Here's a gif for Screenshot Saturday.

 

JeffG

Member
Oct 27, 2017
917
Edmonton, Alberta
So I'm working with animator state behaviours right now and I have a question if anyone can help. I have an NPC, the NPC has an AI script that controls things like animator parameters and etc. He has a baseFSM class with a few variables (reference to the player etc) that all of his state behaviours inherit from. I want to give the NPS a patrol behaviour and I'm having some issue.

Right now in his patrolbehaviour script on awake it looks for an array of objects tagged "waypoint" then he moves through the circuit. This is fine and it works but it isn't ideal because any instances of the npc I put in a level will all share the same waypoint circuit. My thinking is, have a child game object on the npc that contains an array of waypoints specific to that npc, get the reference in the AI script and pass it to the animator behaviour script...

For some reason I'm having the damnedest time with passing a reference to the array into the animator behaviour scripts. I'm sure I'm making it harder than it has to be... ugh. Anyone know how i could do this (create original reference to Transform[ ] waypoints on the NPC AI script ---> reference said array in NPS Animator State base script ----> look up the [ ] in the PatrolBehaviour script).

SOLVED: my dumb self forgot to call the function I made to populate the array :/ crisis averted!
maybe this will help you (see how he references the soundcollection)

 

Weltall Zero

Game Developer
Banned
Oct 26, 2017
19,343
Madrid
Congrats! That's a really nice milestone to reach! :) Is it a smooth process transferring your project folder from Unity to the Switch Version of Unity?

I think I mentioned at some point that there was a standalone version of Unity for the Switch, but I was actually sorely mistaken. What you download is a plugin that you add to Unity itself, which allows you to change your build target to Switch (much like you would to Mac, etc), which is so much better than having two separate environments or project folders. Sorry for the misinformation, although I'm very glad to have been wrong!

You also use the same project folder for all builds. Unity automatically defines compiler variables depending on what build you have selected, which allows you to have code that is specific for a build:
Code:
#ifdef UNITY_SWITCH
    Debug.Log ("I'm a Switch!");
#else
    Debug.Log ("I'm not a Switch!");
#endif

As for the process, it's relatively straightforward and Nintendo's software and documentation is absolutely top-notch, but I still got stuck a couple of times preparing everything because there's quite a few things to learn. One very important thing is that the Switch has its own file system that you need to use to save / load your savegame: for the time being I've simply disabled it on Switch. I'm still trying to figure out if there's a way to step-by-step debug on Switch hardware with the original C# code, because to run on Switch, your code goes through an IL2CPP process that converts it to C++ (and mangles it beyond human readability). This building step, incidentally, is often excruciately slow even on an SSD, so I've taken to multitask whenever I have to try several builds on Switch.

The one thing that gave me the biggest headache was that the joycons weren't registering any input at all: eventually I discovered that they were being assigned to the "keyboard" player because in my game it has the id of 0, and by default Rewired on Switch assigns controllers strictly to the numbers they are assigned by the Switch itself, therefore that player's "don't assign controllers to this player" flag was entirely ignored.

I'm very happy that the game runs at near-locked 60 FPS, that was my biggest worry. In fact, my first attempt was using a debug build, which often dips to 30-40 FPS. But the release build performs so much better, even with lots of particles and building debris onscreen, which is a massive relief as optimizing the game further could probably be pretty hard.

I'm not sure if I'm leaving anything out, hahah. If anyone has any questions please be sure to ask!
 

Qwark

Member
Oct 27, 2017
8,169
Thanks for all of the help here this week! Made some big steps in animation, sprite design, and resolution.

 

Lady Bow

Member
Nov 30, 2017
11,456
I think I mentioned at some point that there was a standalone version of Unity for the Switch, but I was actually sorely mistaken. What you download is a plugin that you add to Unity itself, which allows you to change your build target to Switch (much like you would to Mac, etc), which is so much better than having two separate environments or project folders. Sorry for the misinformation, although I'm very glad to have been wrong!

You also use the same project folder for all builds. Unity automatically defines compiler variables depending on what build you have selected, which allows you to have code that is specific for a build:
Code:
#ifdef UNITY_SWITCH
    Debug.Log ("I'm a Switch!");
#else
    Debug.Log ("I'm not a Switch!");
#endif

As for the process, it's relatively straightforward and Nintendo's software and documentation is absolutely top-notch, but I still got stuck a couple of times preparing everything because there's quite a few things to learn. One very important thing is that the Switch has its own file system that you need to use to save / load your savegame: for the time being I've simply disabled it on Switch. I'm still trying to figure out if there's a way to step-by-step debug on Switch hardware with the original C# code, because to run on Switch, your code goes through an IL2CPP process that converts it to C++ (and mangles it beyond human readability). This building step, incidentally, is often excruciately slow even on an SSD, so I've taken to multitask whenever I have to try several builds on Switch.

The one thing that gave me the biggest headache was that the joycons weren't registering any input at all: eventually I discovered that they were being assigned to the "keyboard" player because in my game it has the id of 0, and by default Rewired on Switch assigns controllers strictly to the numbers they are assigned by the Switch itself, therefore that player's "don't assign controllers to this player" flag was entirely ignored.

I'm very happy that the game runs at near-locked 60 FPS, that was my biggest worry. In fact, my first attempt was using a debug build, which often dips to 30-40 FPS. But the release build performs so much better, even with lots of particles and building debris onscreen, which is a massive relief as optimizing the game further could probably be pretty hard.

I'm not sure if I'm leaving anything out, hahah. If anyone has any questions please be sure to ask!

Very interesting. Thanks for the breakdown. 👍
 

FLCL

Member
Oct 27, 2017
1,548
This is an excellent question because syncing logical / code states with Unity's animation system tends to be a headache. One of the ways I did it is by using a not-very-publicised feature that allows you to add scripts to the animation states themselves, with functions that get called when the character enters or exits a given animation state.

If you make a class like this:

Code:
using UnityEngine;

public class MyAnimationState : StateMachineBehaviour {

    override
    public void OnStateEnter (Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
        base.OnStateEnter (animator, stateInfo, layerIndex);
        // Do stuff.
    }

    override
    public void OnStateExit (Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
        base.OnStateExit (animator, stateInfo, layerIndex);
        // Do stuff.
    }
}

Then add it to any animation state, these functions will be called when the animator enters and exits that state. You can easily use it to lock your character out of performing any other action or moving.
Oh that actually looks very useful! Will circle back to it if my solution turns out to be broken.
 

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
weltall i added a basic 'enemies approach you slowly and try and get in position around you' script and... yeah game feels way better already lol

gotta keep tinkering with it
 

Deleted member 62221

User requested account closure
Banned
Dec 17, 2019
1,140
I remember doing something like that once for AI, if I remember correctly I also had to set transitions and exit time to zero in every state or those events would trigger with a delay.

In the topic of AI, I can't find good code samples on strategic AI (like for a 4X game), everything is about finite state machines, behaviour trees, etc. apparently goal oriented and "HTN" are good techniques but frankly I need to see code to understand these concepts better.

EDIT: ok, this seems interesting. I'll research it a bit.
 

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
Weltall Zero this is your fault



need to work on group dynamics and completely revamp the entity pusher/interact code... right now you 'bounce' off enemies which isn't what I want to happen, but my last fix made it possible to run right through enemies...
 
Oct 26, 2017
4,017
Oh my goodness what a week it has been...

Not much to update on the visual side of things, but a lot of bug-fixes under the hood! I fixed my camera so that it now moves smoothly, consistently and without pixel-jitter, but in turn that caused an issue when the camera was following replay players, so I had to investigate that! (They were very, very jittery)

Turns out I had been recording the positions of my entities (for the purposes of replay) incorrectly this whole time, but it was "close enough" that it looked correct until I got the camera to work properly. That took a few days to track down! On the plus side, in doing so I also discovered that I had implemented a hideously inefficient replay-playback method, so I optimized that into something much faster. Same big O (order of N) but the actual number of iterations in a loop per frame has gone down from potentially thousands to probably 10 at the very most. I have no idea why I built it that way to begin with!

And then I optimized my pixel-perfect camera clamp logic so that it doesn't use divisions anymore. I'll post it here if anyone wants to steal it. It can also be used to clamp any entity to a pixel-perfect location too, which might be handy depending on your game (Or it could end up breaking everything horifically, so be careful!) Written in c# for unity but the logic should be applicable to anything else.

Code:
protected float CalculatePixelPerfectPosition(float unperfectPosition)
    {
       
        //Calculate the position in pixel-space (Still  a floating point number at this point)
        float resolutionPosition= unperfectPosition * m_pixelsPerUnit;

        //Truncate the calcualted position to an integer and store in a seperate variable
        int resolutionPositionInt = Mathf.FloorToInt(resolutionPosition);

        //Subtract the integer component of the resolution to get a decimal "remainder"
        resolutionPosition -= resolutionPositionInt;

        //If the reaminder is greater than or equal to 0.5 (half a pixel) then increase the value of the integer position
        if(resolutionPosition >= 0.5)
        {
            resolutionPositionInt++;
        }

        //Convert the resolution position back into Unity co-ordinate space by multiplying by the reciprocal (1/PixelsPerUnit)
        return resolutionPositionInt * m_pixelsPerUnitReciprocal;

    }


Weltall Zero this is your fault



need to work on group dynamics and completely revamp the entity pusher/interact code... right now you 'bounce' off enemies which isn't what I want to happen, but my last fix made it possible to run right through enemies...


What do you want to happen? Collision response is always a tricky one when you're getting started! (Animations look slick btw)
 

Weltall Zero

Game Developer
Banned
Oct 26, 2017
19,343
Madrid
Weltall Zero this is your fault



need to work on group dynamics and completely revamp the entity pusher/interact code... right now you 'bounce' off enemies which isn't what I want to happen, but my last fix made it possible to run right through enemies...


Hahah, glad it helped. It's hard to find the balance between not being too nosy with other people's projects, but still trying to correct course when they seem to have gone a bit off-track. Glad you didn't take it the wrong way. :)
 

Weltall Zero

Game Developer
Banned
Oct 26, 2017
19,343
Madrid
Oh my goodness what a week it has been...

Not much to update on the visual side of things, but a lot of bug-fixes under the hood! I fixed my camera so that it now moves smoothly, consistently and without pixel-jitter, but in turn that caused an issue when the camera was following replay players, so I had to investigate that! (They were very, very jittery)

Turns out I had been recording the positions of my entities (for the purposes of replay) incorrectly this whole time, but it was "close enough" that it looked correct until I got the camera to work properly. That took a few days to track down! On the plus side, in doing so I also discovered that I had implemented a hideously inefficient replay-playback method, so I optimized that into something much faster. Same big O (order of N) but the actual number of iterations in a loop per frame has gone down from potentially thousands to probably 10 at the very most. I have no idea why I built it that way to begin with!

And then I optimized my pixel-perfect camera clamp logic so that it doesn't use divisions anymore. I'll post it here if anyone wants to steal it. It can also be used to clamp any entity to a pixel-perfect location too, which might be handy depending on your game (Or it could end up breaking everything horifically, so be careful!) Written in c# for unity but the logic should be applicable to anything else.

Code:
protected float CalculatePixelPerfectPosition(float unperfectPosition)
    {
      
        //Calculate the position in pixel-space (Still  a floating point number at this point)
        float resolutionPosition= unperfectPosition * m_pixelsPerUnit;



        //Convert the resolution position back into Unity co-ordinate space by multiplying by the reciprocal (1/PixelsPerUnit)
        return resolutionPositionInt * m_pixelsPerUnitReciprocal;

    }

I may be missing something obvious, but isn't this whole part:

Code:
        //Truncate the calcualted position to an integer and store in a seperate variable
        int resolutionPositionInt = Mathf.FloorToInt(resolutionPosition);

        //Subtract the integer component of the resolution to get a decimal "remainder"
        resolutionPosition -= resolutionPositionInt;

        //If the reaminder is greater than or equal to 0.5 (half a pixel) then increase the value of the integer position
        if(resolutionPosition >= 0.5)
        {
            resolutionPositionInt++;
        }

... the same as simply doing:
Code:
        int resolutionPositionInt = Mathf.RoundToInt(resolutionPosition);
 
Oct 26, 2017
4,017
I may be missing something obvious, but isn't this whole part:

Code:
        //Truncate the calcualted position to an integer and store in a seperate variable
        int resolutionPositionInt = Mathf.FloorToInt(resolutionPosition);

        //Subtract the integer component of the resolution to get a decimal "remainder"
        resolutionPosition -= resolutionPositionInt;

        //If the reaminder is greater than or equal to 0.5 (half a pixel) then increase the value of the integer position
        if(resolutionPosition >= 0.5)
        {
            resolutionPositionInt++;
        }

... the same as simply doing:
Code:
        int resolutionPositionInt = Mathf.RoundToInt(resolutionPosition);

Could very well be, I didn't know RoundToInt was a thing, haha!
 

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
What do you want to happen? Collision response is always a tricky one when you're getting started! (Animations look slick btw)

basically you should either hit 0 velocity when you hit the boundaries of a colliding entity (usual collision detection) or, if the entity's collision reactivates while you're inside it, both entities should shove each other away (necessary because of states that disable collision etc). Unfortunately because of the way my velocity/movement system works right now you can shove people around when they should be static etc... might need to rethink how it works (maybe instead of being parent entity based it'll just have to revolve entirely around the player... I hope not)
 

jarekx

Member
Oct 25, 2017
625
It's fun when you come up with a solution to a problem that you know isn't probably the 'correct' way to do it but it's what you can wrap your head around at the moment, lol.
 

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
i got the collision working right (woke up with the solution as happens often), now grappling with group dynamics for AI (probably as simple as drawing out a proper AI flowchart and having a simultaneous attacker list that enemies need to check against before initiating an attack)

im sure weltall would tell me to code the actual enemy damage first but noooooooooooooo leave me alonnnneeee
 

Weltall Zero

Game Developer
Banned
Oct 26, 2017
19,343
Madrid
i got the collision working right (woke up with the solution as happens often), now grappling with group dynamics for AI (probably as simple as drawing out a proper AI flowchart and having a simultaneous attacker list that enemies need to check against before initiating an attack)

im sure weltall would tell me to code the actual enemy damage first but noooooooooooooo leave me alonnnneeee

Okeeeeeeeey. :D

For the simultaneous attack thing, let me share something correojon told me about that I implemented in Divinoids and worked fantastically: the token system. The idea is quite simple; you have a pool of "attack tokens" (think of these as actual, physical tokens in a bowl). When an enemy wants to attack, they try to grab a token from the list; if the list is empty, they can't attack. When they're done attacking, they return the token to the list. You can modify that to do all sorts of cool stuff like having special boss tokens, giving a cooldown to each token before it can be used again, etc. etc. it's super flexible. :)
 

K Monkey

Member
Oct 25, 2017
278


Testing out some of the characters outside. Worked pretty well but made me realise that I now want him to be able to knock down those trees!
 

correojon

Banned
Oct 26, 2017
1,410
Okeeeeeeeey. :D

For the simultaneous attack thing, let me share something correojon told me about that I implemented in Divinoids and worked fantastically: the token system. The idea is quite simple; you have a pool of "attack tokens" (think of these as actual, physical tokens in a bowl). When an enemy wants to attack, they try to grab a token from the list; if the list is empty, they can't attack. When they're done attacking, they return the token to the list. You can modify that to do all sorts of cool stuff like having special boss tokens, giving a cooldown to each token before it can be used again, etc. etc. it's super flexible. :)
Hello! All the credit for this system goes to the Doom (2016) devs, there are some cool videos and articles about this system floating around, I recommend searching for them. The great thing about this system is how simple it is to implement and how flexible it is just like Weltall Zero says. You can make different types of tokens, like ranged and melee, or for special attacks from powerful enemies that have long cooldowns. You can make enemies steal tokens from each other (like when an enemy suddenly find itself right in front of the player and needs to attack) or quickly implement a difficulty system by altering the cooldowns or the number of tokens in the system. You can also add special conditions for requesting tokens so that enemies won't attack while others are attacking...you can do a lot of cool things!
 

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
Okeeeeeeeey. :D

For the simultaneous attack thing, let me share something correojon told me about that I implemented in Divinoids and worked fantastically: the token system. The idea is quite simple; you have a pool of "attack tokens" (think of these as actual, physical tokens in a bowl). When an enemy wants to attack, they try to grab a token from the list; if the list is empty, they can't attack. When they're done attacking, they return the token to the list. You can modify that to do all sorts of cool stuff like having special boss tokens, giving a cooldown to each token before it can be used again, etc. etc. it's super flexible. :)

i think that's basically my list system but i'll see how it looks on implementing

while i've got your ear i wanted to pick your ear about managing group dynamics on a single 2d plane, how's that working out? Can your enemies overlap one another, how do you avoid clumping, how's it work with ranged enemies and other non stand-next-to-player-and-attack types?

Hello! All the credit for this system goes to the Doom (2016) devs, there are some cool videos and articles about this system floating around, I recommend searching for them. The great thing about this system is how simple it is to implement and how flexible it is just like Weltall Zero says. You can make different types of tokens, like ranged and melee, or for special attacks from powerful enemies that have long cooldowns. You can make enemies steal tokens from each other (like when an enemy suddenly find itself right in front of the player and needs to attack) or quickly implement a difficulty system by altering the cooldowns or the number of tokens in the system. You can also add special conditions for requesting tokens so that enemies won't attack while others are attacking...you can do a lot of cool things!

oh sweet thanks for the further recommendation for reading, I'll go look it up

I think it'd be interesting to share the types of articles and tutorials and other resources that we've found particular useful in our time to date and to specify what kind of stuff we're building and how it was useful. I know there's lots of disparate things I should probably consolidate for future reference or to recommend on (or even to archive in some cases given the general impermenance of the net)
 

jarekx

Member
Oct 25, 2017
625
Damn, that token system is a cool idea. I'll have to keep that in mind for real time projects.

I have a much larger project idea in mind that i'm putting on the back burner and trying to figure out a bunch of stuff before I start actually making it. It's actually one I've had in mind for a while so i'm just trying to put some more substance and detail into my plan. I may actually go with RPG Maker for that as I like the eventing system and the database out of the box. It also seems to use JS for it's scripting system so that shouldn't be too hard a transition from GML. There's also a new version coming this summer, but details are sparse so maybe I'll wait and see what they've added with that and decide if it's worth it. If anyone has any experiences, good or bad with RPG Maker, let me know. I've seen some great stuff with it, so i'm sure it's just a matter of putting the work in.

Until then, i'm just making a simple light deck builder. Well, you don't pick many indiviudal cards but each is tied to a piece of equipment, so as you switch gear your deck changes and modifies. I'm trying to take Weltall Zero 's advice and just get a Minimum Viable going before I worry about fleshing everything out. Definitely feels a lot more manageable when you focus on just getting each piece into play

Is that a lane based fighter Jintor ? That's a pretty cool idea.
 

Weltall Zero

Game Developer
Banned
Oct 26, 2017
19,343
Madrid
i think that's basically my list system but i'll see how it looks on implementing

There's several differences, the main one being that whenever each enemy attacks, they don't have to traverse the full list of enemies to see who's attacking. With a lot of enemies onscreen, that could be inefficient especially as each one of them wants to attack (worst case, it would be quadratic). The token system is a lot more flexible too with minimal extra code.

The core insight is that these tokens are actual logical objects that, when not in use, are stored in a "available tokens" list. The tokens themselves can have a lot of information.

while i've got your ear i wanted to pick your ear about managing group dynamics on a single 2d plane, how's that working out? Can your enemies overlap one another, how do you avoid clumping, how's it work with ranged enemies and other non stand-next-to-player-and-attack types?

Excellent question! I have no clue if it's the best way to implement it, but this is the way I did it. It's not terribly complicated but also not trivial and a bit circular to explain, so bear with me:

- Each enemy contains a "target position", which is where they want to move to.
- There's also a global list that contains all target positions of all enemies.
- When an enemy wants to move somewhere else, they:
1) Remove their own, current target position from the list.
2) Calculate their target position (more on this below).
3) Add their own, final target position to the global list.

That's kind of the easy part. Now, the way I calculate an enemy's target position is:
2.1) Each enemy type has an "ideal" distance from the player. In my case it's a vector (x and y), since some enemies fly.
2.2) The enemy calculates a potential target position, and checks if it overlaps* any other enemies' target position. If it does, it keeps going through potential target positions until it finds one that doesn't overlap anyone else's target position.

The order that enemies' check potential target positions are:
2.2.1) The position that's at their "ideal" distance from the player, at the side (left or right) they currently are. This is to prevent enemies from changing from one side of the player to the other for no reason.
2.2.2) The position that's at their "ideal" distance from the player, at the opposite (left or right) they currently are.
2.2.3) Positions further away and further up from the player, until a free one is found.

*"Overlaps" specifically means that the distance between both target positions is smaller than a certain amount. That is, enemies cannot be closer together than this amount.

In your case a lot of the calculations will be simpler since you don't have flying enemies. You can simply use the X of each enemy instead of their X,Y position.

At the time I implemented it, I tweeted about it. The "swarm" behaviour it results in is quite satisfying to watch. :D
 

stan423321

Member
Oct 25, 2017
8,676
Random question: if I have a melody, how can I reasonably test if it's not accidentally plagiarizing something? I caught myself with one of my "originals" being directly taken from a source I paid half attention to, and now I'm starting to reconsider use of stock stuff to shift the blame just in case...
 

Jintor

Saw the truth behind the copied door
Member
Oct 25, 2017
32,765
There's several differences, the main one being that whenever each enemy attacks, they don't have to traverse the full list of enemies to see who's attacking. With a lot of enemies onscreen, that could be inefficient especially as each one of them wants to attack (worst case, it would be quadratic). The token system is a lot more flexible too with minimal extra code.

The core insight is that these tokens are actual logical objects that, when not in use, are stored in a "available tokens" list. The tokens themselves can have a lot of information.

Thanks for the anti-clumping ideas, I'll think about that next too

I'm just trying to visualise how to implement the tokens. I was thinking a ds_grid where you'd list the tokens then list whatever object is currently in posession of it (so index 0 would be: token, attacker_ID) and then attackers would reserve or free up their slot depending on states/actions but it seems faster to just ask you how you did it! (Also searching for token AI programming implementation is noisy because token is already an accepted term in programming)
 
Status
Not open for further replies.