#novice with very simple 2D project (need basic advice...)

35 messages · Page 1 of 1 (latest)

solemn wave
#

project repo: https://github.com/meisei4/yakuzaishi (Edit: This is the main branch only for now, i have been updating things on other branches based on replies in this thread) Hello, I am a novice programmer and have been working on a very simple bevy practice project.

My entities so far are:
1.** TiledMap** (using https://docs.rs/bevy_ecs_tilemap/latest/bevy_ecs_tilemap/ and some hacky implementation of the asset loading: ||this i am not concerned about getting advice on exactly right now because i hope to do a custom solution in the future, since there doesn't exist a proper crate to help with it yet||
2. Player Entity - very simple keyboard input control and transform (also only a single frame for animation)
3.** Animations ** - Simple animations based on how i originally implemented the tile animations on my own
4. **Environment Entity ** - My most recent feature that kind of takes from all of the stuff i learned from the previous entity implementations combined

^^I have reached a point where I have added enough entities to realize that I am maybe doing things pretty inefficiently. My main concerns are in how I have organized the project so far, and how I am starting to fall into a trap of copy and pasted code. (very obvious in the EnvironmentEntity + AnimationResource implementation)

**REQUEST FOR ADVICE: **I am hoping i can get advice on what libraries i should look into, and perhaps how i should continue with this project before I continue to fall deeper into copy and paste spaghetti structure... Any advice would help.

#

code that I would like advice on specifically is:

load state logic for player_entity

run state/Update logic for player_entity

load state logic for animations

load state/Update logic for animations

State Plugins: https://github.com/meisei4/yakuzaishi/blob/master/src/states.rs

^^^ Examples for how i have been writing Systems and States
I think how I am controlling states seems ugly to me (OnEnter, Update, OnExit, and asset loading issues with order of asset loading). I have refactored many times but i think i am missing something critical in how i am approaching this issue in the first place...

#

https://github.com/meisei4/yakuzaishi/blob/master/src/systems/entity_runtime/camera.rs

^^Camera and map design issue
I started the project thinking that BOTTOM-LEFT was appropriate (coming from a math coordinates background...😢 ), but have recently concluded that I want to convert everything to TOP LEFT. But Im having trouble figuring this out on my own... The issue I believe is especially clear with how my Camera is unable to "Clamp" to the map borders how i am expecting. The clamping logic only seems to work with clamping to top border and right side border... (otherwise it on the bottom and left border it doubles the size of my maps coordinates)

#

I am really hoping that I can learn of some libraries that might make 2D bevy projects more simple than my current ugly custom attempts...

Any advice is VERY APPRECIATED🙏🙇‍♂️

#

PlayerEntity's texture, and the EnvironmentEntity animation (dolphin diving) are custom drawn. The water tiles and random white spiral animation overlayed on the PlayerEntity are from itch.io free assets...)

tender remnant
#

Haven't had time for an in-depth look, but couple of quick thoughts:

  • look into https://github.com/NiklasEi/bevy_asset_loader , it's a great little pattern for guaranteeing asset availability and handles the state transition for you
  • player spawning: it's (IMHO) unusual to see individual calls to e.g. GlobalTransform::default(). Usually you can just use a bundle, probably a Sprite2DBundle. For example:
    commands.spawn(Player).insert((
        TextureAtlas {
            index: idle.first,
            layout,
        },
        SpriteBundle {
            texture: texture_assets.kiwi.clone(),
            transform,
            ..default()
        },
        idle,
        tile_pos,
    ));

and whatever other bundles or components you might need. I see you're inserting that elsewhere, particularly in your animation code, but I don't really understand why you wouldn't just spawn it all with the player entity. Saves mucking around with transforms more than you absolutely have to. (But I might be missing a particular requirement of your game).

  • look into https://github.com/Leafwing-Studios/leafwing-input-manager, it's great
  • having a plugin for each of your gamestates (load, run, etc.) is an interesting approach but you might want to think about going more fine-grained than that. I would imagine that the plugin for while the game is running would get quite large and unwieldy over time.
solemn wave
#

I actaully have not been using Bundles at all for the Entity template thing, I am just about to start doing that after looking through the Bevy Cheatbook a little more closely

tender remnant
solemn wave
#

thanks alot, i will take a look at this over this week when i have time! will respond in this thread a little more to post updates i make based on these new crates and references

solemn wave
tender remnant
#

Honestly I felt exactly the same, I'm not going to be using it 100% but the spawning pattern is really nice

solemn wave
#

just to get another opinion, i have this issue ticket that i think (after rereading your comment) relates to my abuse of spawning/weird loading design...

And I am assuming its very much related to my lack of using Bundles, and the bevy_asset_loader crate. But I am honestly confused on this choice between creating a Resource over a Component...

https://bevy-cheatbook.github.io/programming/res.html
In the fourth paragraph of this page, it says:

***Types must be unique; there can only be at most one instance of a given type. ***If you might need multiple, consider using entities and components instead.

And I still dont think i understand what that means, because in my head I think of how I use Resources is as like a "game asset" (i.e. consisting of some file format that gets loaded at somepoint), but apparently based on my design of the animations and "EnvironmentEntity" vs "PlayerEntity", i am conflicted on whether or not this justifies a Resource anymore (for some reason i don tlike the idea of handling a "File"/asset for some entity as a Component)...

#

here is the code i have that i think is conflicting with this idea of using REsources over Components

#

^These essentially serve as 3 identical Resources... but because:

Types must be unique; there can only be at most one instance of a given type.

I end up just renaming the exact same structure to achieve that uniqueness... and i really dont like doing that...

solemn wave
#

(I think I am actually still genuinely confused about "commands.spawn()", in the context of stuff that I dont want to treat as an Entity...

https://github.com/meisei4/yakuzaishi/blob/master/src/systems/entity_loadtime/tiled_map.rs

please take a look here at the TiledMapBundle "spawn" call... maybe I am being annoying about the word "spawn", but i think it should only be for things that are purely Component collections/Entity templates... But maybe thats the whole meaning of the word Bundle... I still dont understand it 100% (I think i am mixing up the concept of Resource and Entity too much because of this).

I only want to use something that handles "Files"... like literal asset stuff: .png, .tmx, .gif, etc (in this case a Handle to a map file/.tmx/.tsx) in the context of a "Resource".

But I guess this is not the correct way to think about things in ECS? and maybe i should start treating these assets/files as Components?

tender remnant
#

ah, so this:

I only want to use something that handles "Files"... like literal asset stuff: .png, .tmx, .gif, etc (in this case a Handle to a map file/.tmx/.tsx) in the context of a "Resource".
almost exactly describes what bevy_asset_loader does, so I do recommend checking that crate out. You essentially subdivide your assets into resources, which can then be accessed during the game via systems:

fn do_the_thing(texture_assets: Res<TextureAssets>) {
  // ...use e.g. texture_assets.player here, which will be a Handle<Image>
}
#

for my money, it takes a lot of the fuss out of working with assets and the author (Niklas Eicker) has a number of other useful Bevy crates in their GitHub.

#

when I mentioned the spawning pattern, I meant what happens in https://github.com/TheBevyFlock/bevy_quickstart/blob/main/src/demo/level.rs, which demonstrates something I hadn't even thought of: essentially a way to provide a neat, composable, configurable pattern to spawning in game entities e.g.:

    SpawnMap {
        // ... map config
    }.apply(world);
    SpawnPlayer {
        // ... player config
    }.apply(world);
    SpawnBoss {
        // ... boss fight config
    }.apply(world);

We can fairly easily see how such config could be loaded in from file, or network, or other sources, and spawns can trivially be made conditional e.g. only spawn the boss in hard mode.

#

This, for me at least, reduces the occurrence of Giant Functions of Doom that were tending to find their way into my games 😆

solemn wave
pale falcon
solemn wave
# pale falcon I'm working on my own TiledMap thing myself actually if you wanna collab on that

@pale falcon Did we have similar TiledMap Thread together way back haha, I am interested in this, but I am also thinking I am not ready to put alot of time in it. I also have a feeling that there havbe been some big changes in 0.14 that i havent learned about yet, that might help solve the bevy_ecs_tilemap issue with .tmx and stuff. So I dont think im ready, but i will post some stuff hopefully here about what i learn of the asset loader crate.

(I have been pretty busy with other things recently, so need to regain momentum on my project first, i still havent implemented the stuff in this thread that i hope to yet)

pale falcon
#

Not that I know of

split hamlet
#

https://github.com/meisei4/yakuzaishi/blob/master/src/systems/entity_loadtime/player_entity.rs

I think this would greatly benefit from separating in an input collection and a player movement function.
collect/record "player intent" (movement or input in general) in one function and then act on some of the recorded input in another function

this will give you more flexibility later, when you want to do keyboard remapping or have different inputs for camera etc.

Maybe check out the leafwing crate https://crates.io/crates/leafwing-input-manager
It's a great addition :)

#

I think that you shouldn't collect all constants in lib.rs but it's more intuition than actual knowledge, something about it feels... off?

I think if you have the time, you should group parameters into Settings and inject them as resources. Then you can change them during runtime (like mouse sensitivity) or even load them from file, which means no more recompiling for testing simple values.

solemn wave
#

@split hamlet Thanks so much for the added comments I have been meaning to refactor a lot of my stuf to take advantage of Bundles (for some reason I didnt understand the purpose of them just from the name and having tried to read the official docs way back, so i ignored it until now, and now i really want to use them.

Also thanks for the input on the input system! I will check that out too.

Also I agree with the libs.rs since it is getting much heavier than I was expecting it to get at this point, so i think i will try to experiment with moving them closer to their actually referenced scopes etc.

I think if you have the time, you should group parameters into Settings and inject them as resources.

This is actually a great idea, now that i know how Resources are used better... will take a look at doing this.