dragbone

joined 2 years ago
[–] [email protected] 3 points 1 month ago

I guess you are right, if it were that potent at stopping spoiling we wouldn't need all the chemicals we use today to preserve foods :D I'll try cleaning the lemons more aggressively and see if it helps :D

[–] [email protected] 3 points 1 month ago

Good to know, I'll try again but will make sure the better clean the lemons!

[–] [email protected] 2 points 1 month ago

Juice shouldn't be the problem because the other half of my brew without the peel (but also with juice) worked without a problem. But good to know that the lemon itself should work, might be due to pesticide on the lemons...

[–] [email protected] 3 points 1 month ago

Good to know it should work in general. I'll try again :)

[–] [email protected] 2 points 1 month ago

It was a very small amount of thinly sliced lemon peel (less than a teaspoon). From the other comments I'm guessing that the lemon was treated with a pesticide that also killed my fermentation.

[–] [email protected] 2 points 1 month ago

Good to know, I'm going to blame the lemons I used and try again!

[–] [email protected] 3 points 1 month ago

Thanks for your comment! Kefir might be more sensible to whatever treatment the lemons got, I guess I'll try washing with hot water :)

22
submitted 1 month ago* (last edited 1 month ago) by [email protected] to c/[email protected]
 

I've been brewing lemonade with a ginger bug and water kefir for quite a while. But whenever I try to incorporate lemon peel it seems to completely halt fermentation. I have tried normal and organic lemons without success. Currently I have a small batch of kefir with lemon juice going. Half of the batch is with lemon peel and that half shows no sign of fermentation after 30 hours (I have already bottled the other half because it was ready). Did any of you have similar experiences? I would really like to include peel for the taste 🙃

EDIT: Thanks for the many inputs! Summarizing the responses it seems like lemon peel doesn't inherently stop fermentation and the cause is more likely to be whatever pesticide the lemons were treated with. So I got myself a very expensive (supposedly) untreated lemon which I will use in my next brew (after washing it thoroughly) and continue from there.

[–] [email protected] 2 points 1 year ago

There's not much currently, but you can follow my progress on mastodon if you want: https://mastodon.gamedev.place/@dragbone I hope I can find a name for it soon 😅

[–] [email protected] 10 points 1 year ago (2 children)

This week I have added a thorns ability so enemies can defeat themselves without you having to lift a single finger... or hammer 🔨

[–] [email protected] 6 points 1 year ago (1 children)

Had a very productive week ☺️ 🐢-character got a new attack animation, fixed a bug with normals, added defeat animations to all characters and implemented instanced rendering for particles. Also learned how to use davinci resolve to make videos: https://mastodon.gamedev.place/@dragbone/112105598167777885

[–] [email protected] 9 points 1 year ago

During development I usually only playtest myself. But I found a way to trick myself into doing it right: I create an android build of my game every day and load it onto my tablet to play in bed or on the couch. That forces me to just play the game as it is and create bug and balance tickets for whatever I encounter. Not sitting at the computer helps me separate myself from game development and provide more honest feedback.

[–] [email protected] 4 points 2 years ago (1 children)

Each pack has about 5 themed tracks, each about 2min long. So I would say worth it for prototype or small game but not really enough content for a full game.

17
submitted 2 years ago* (last edited 2 years ago) by [email protected] to c/[email protected]
 

click here to view this on my blog with some nicer styling

Most developers that have had some experience with programming business software are familiar with testing, especially unit testing. But that experience usually doesn’t transfer neatly into gamedev due to the fact that games are more about interaction between game elements rather than the behavior of a single element alone. Never the less, unit testing can be a powerful tool, even when it comes to game development. Test with a larger scope than unit tests can also provide interesting possibilities that aren’t talked about enough. I’ll try to change that and hope to inspire you to try out some different forms of automated testing.

Starting simple – Unit Tests

Let’s first get some basics out of the way and start with unit tests and when to use them. Unit tests are the most useful whenever you have some complex logic that is at least somewhat isolated. As an example from my current game/prototype I had to write a method that computes if and when in the future two moving circular hit boxes will overlap.

This method is used to predict when two units would collide and helps steer them apart. The result isn’t perfect (yet) but is already a lot more natural than any collision based system.

The method signature looks something like this (Warning! Two letter variables ahead):

fun computeCollision(
    // position, velocity and radius of first hitbox
    p0: Vector, v0: Vector, r0: Double, 
    // position, velocity and radius of second hitbox
    p1: Vector, v1: Vector, r1: Double
): Double? {
    /* complex logic goes here */
}

Writing some unit tests helped me iron out some edge cases that such e piece of code might have:

  • What happens if the circles have intersected in the past?
  • What happens if the paths the circles take never intersect? (e.g. parallel movement)
  • What happens if the paths never intersect but the circles do (e.g. parallel movement but they always intersect)
  • What happens if the circles touch but never intersect?

Given that the logic completely depends on the inputs it is very easy to write unit tests:

@Test
fun `two circles with crossing paths at different times should never collide`() {
    val t = computeCollision(
        // Will pass (0,0) after 5 seconds
        p0 = Vector(-5f, 0f), v0 = Vector(1f, 0f), r0 = 1.0,
        // Will pass (0,0) after 8 seconds
        p1 = Vector(0f, -8f), v1 = Vector(0f, 1f), r1 = 1.0
    )

    expectThat(t) { isNull() }
}

This is nice for isolated methods, but can get complex and convoluted if you want to test interactions between different things in your game. Which is why we need to take this…

One level higher – Gameplay Tests

The prerequisites to efficiently test gameplay is that your game engine supports it. Sadly that isn’t a given by most common game engines, so you’ll have to make do with some weird hacks depending on your choice of tooling. In my case it was rather easy because I’m not using a real game engine but something like a game framework (libgdx + ktx). In addition I’m using the Entity Component Systems (ECS) design pattern (powered by fleks) for my game logic, which makes it quite easy to run my game as a simulation without any user interface.

Separating out any logic that depends on graphical context (e.g. OpenGL) was as simple as setting up a game world without all rendering systems. The game loop is also completely in my control, so I can easily simulate thousands of frames per second. Any complexity is extracted into easy to use methods. A simple test looks something like this:

@Test
fun `heroes with starter weapons should beat level 1`() {
    // Arrange - setupWorld() uses the same methods to setup the world as the 'real' game
    //           but without any rendering logic. It also mocks user input to cast
    //           skills at enemies.
    val (world, gameHandler) = setupWorld(level = 1, defaultBow, defaultSword)

    // Act - simulate the gameloop at 30fps until the heroes win or lose
    val result = world.simulateLevel(gameHandler)

    // Assert - check if simulation finished with the expected result
    expectThat(result) { isEqualTo(GameOutcome.Win) }
}

This simulates a full run of the first level in about 100ms. With this setup it is quite simple to add various scenarios for different enemies, heroes and item combinations and run them in a short amount of time in order to ensure everything works as expected. But why stop here?

Let’s turn it around – Game Balance Tests

Given that we can run through multiple levels under a second, why not automate some more tasks that you would normally do by hand? Let’s test some simple game balance assumptions that should always hold true.

A test to check that a very good item crafted at level X should be able to beat level X+1 could look like this:

// Parameterized tests run the same test multiple times with different inputs
@ParameterizedTest(name = "should beat level {0}")
@ValueSource(ints = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
fun `best crafted item from previous level`(level: Int) {
    // getBestCraftedItem() simulates randomly crafting items at a given level
    // the best item out of 100 crafted items from the previous level is selected
    val (world, gameHandler) = setupWorld(
        level,
        getBestCraftedItem(level - 1, ItemType.Bow, numItemsToGenerate = 100),
        getBestCraftedItem(level - 1, ItemType.Sword, numItemsToGenerate = 100)
    )

    val result = world.simulateLevel(gameHandler)

    expectThat(result) { isEqualTo(GameOutcome.Win) }
}

There are many other possible balance tests one could imagine writing:

  • Crafted items should never be so good that it enables skipping a level entirely
  • Heroes should be balanced in a way that multiple of the same hero cannot beat levels but different heroes together can (e.g. 3 knights should be a worse than 1 knight + 1 archer + 1 healer)
  • Different builds should be able to beat levels (e.g. always selecting weapons that deal poison damage should be as viable as picking weapons that deal fire damage)

It’s also quite easy to collect some additional metrics from the world by adding some systems that are only used in tests and that monitor various entities (e.g. count how much damage a certain hero deals compared to other ones). The possibilities are almost endless!

Conclusion

Why would one even go through all this effort? I see the possibilities this brings when used in conjunction with manual gameplay testing. Playing a game to see if it is fun will always be required. But imagine switching some things around and prototyping different ideas while immediately being able to see what consequences that has is immensely powerful. How far one can push this concept is something that I will have to learn as my game grows in features and complexity.

 

Hey there! I'm a free-time gamedev (and full time software engineer) escaping the clutches of reddit and wanted to introduce myself over here. I'm coming back to game development after a longer break due to lack of energy. One job change later and I'm at it again :) I'm currently prototyping a minimalistic action rpg, trying to focus on item crafting (with a mod system similar to but simpler than Diablo 2, Path of Exile, Last Epoch) and some simplified action gameplay. This is my first time trying out ECS as a design paradigm, so far I'm liking it, although there are some mistakes I keep making that start to annoy me. I'll be looking into unit testing in gamedev as that seems to be pretty easy in ECS, has anyone had any experience with that?

I try to regularly upload a build to itch.io if you want to take a look at my progress.

Feel free to comment or write me a message if you have any interesting inputs/ideas or maybe know of a game that tries to achieve something similar.

~dragbone

view more: next ›