Author Topic: Simon blogs  (Read 101595 times)

0 Members and 1 Guest are viewing this topic.

Offline Simon

  • Administrator
  • Posts: 3543
    • View Profile
    • Lix
Re: Simon blogs
« Reply #345 on: January 05, 2023, 05:07:30 PM »
Eating less is probably 70 % of the story and exercising is 20 %. The human body is a machine with input, storage, and output, and now we want to run with a net input/output deficit.

The most direct way to the net deficit is to eat less. Not necessarily less volume, but less energy.

To not be unhappy while eating less:
  • Eat only slightly less at first.
  • Fill the stomach with non-energy filler material. Drink more water or tea.
  • Choose foods with lower energy density. Have cucumber for snacking. The guinea pig diet from OP is to eat cucumber frequently. You can have it on bread as an extra topping, or even have it by itself.
  • In case of munchies: More cucumber.


Exercise is mediocre at burning calories directly. It's for building muscle. Muscle will cost the body energy to maintain, and you gain less fat meanwhile. Building muscle is like building harvesters at the beginning of a real-time strategy game, they'll keep working for you even when you're idle.

I have no experience or deeper knowledge of lopsided diets that force the body into burning fat faster. The regular burning of fat from eating less was good enough in the past for me.

-- Simon

Offline Simon

  • Administrator
  • Posts: 3543
    • View Profile
    • Lix
Re: Simon blogs
« Reply #346 on: January 13, 2023, 06:53:24 AM »
Ancient Treasure Chest

I'll be busy over the weekend. Here are some old pictures for your enjoyment.





We start with some screenshots from Cheapo, the old Lemmings clone from 20 years ago. It's guaranteed unoriginal, and that's very very good. Isn't the man as happy as we are! Well, he was, until I rotated the mouth.




Some toying with sprites from Lemmings 2. I used those lemmings as a forum avatar here around 2005.



One day, I put the lemming onto the chamaeleon, and this is the natural result.



I included this picture in a rant about time limits. Back in the day, level authors customarily reduced the time limit to the lowest possible minute that kept the level beatable. Lix still had time limits and NeoLemmix didn't allow unlimited time.



When I sprited the first few frames of the Lix platformer around 2010, I had this unused Lix sprite. Instead of not using it for anything, I made this little image.



Remix by geoo. Clones didn't like uneven terrain. It's only a mild exaggeration!

-- Simon

Offline chaos_defrost

  • Posts: 904
  • the artist formerly known as Insane Steve
    • View Profile
Re: Simon blogs
« Reply #347 on: January 14, 2023, 01:03:38 AM »
Awwwwww Cheapo Copycat Game, good memories. I still have it on my computer but for like my last 10-15 years of computers it always runs way slower that on the computers I had when it first came out for some reason.
"こんなげーむにまじになっちゃってどうするの"

~"Beat" Takeshi Kitano

Offline mobius

  • Posts: 2697
  • relax.
    • View Profile
Re: Simon blogs
« Reply #348 on: January 14, 2023, 11:44:33 PM »
amazingly Cheapo works 80-90% on my current PC running windows 10. Its a bit slow but not terribly slow. I easily get more frustrated from lack of Lix/NL ease features than old bugs. I contacted Peter Spada last year for a question about Cheapo and he responded promptly. I didn't ask at the time but I wonder if he made any other games?

Every now and then I try to play Clones again and it's just... awful. Nothing about it feels intuitive. A Game of this nature that doesn't always allow you to pause or pausing that doesn't work correctly should be illegal. Sorry to the creator, I know they at one time were present on this forum but this game sucks.

I attached a recent Windows 10 home screen pic.
everything by me: https://www.lemmingsforums.net/index.php?topic=5982.msg96035#msg96035

"Not knowing how near the truth is, we seek it far away."
-Hakuin Ekaku

"I have seen a heap of trouble in my life, and most of it has never come to pass" - Mark Twain


Offline Simon

  • Administrator
  • Posts: 3543
    • View Profile
    • Lix
Re: Simon blogs
« Reply #349 on: January 22, 2023, 06:49:57 AM »
That's a Tamandua, a small anteater. It's not a Tapir. Very much lovely still. :lix-grin:
See also Gronklink's post about tamanduas.

Still so much work on Lix in my free time, I'm beginning to lose sleep over it. I'm 50:50 on whether the endorphines break even with health, or whether the Lix work is getting detrimental. I should probably schedule a day where I don't look at the source at all, don't play Lix, and don't check Lemmings Forums. Some time after 0.10.5 is out, which should release in the next few days.

-- Simon

Offline Simon

  • Administrator
  • Posts: 3543
    • View Profile
    • Lix
Re: Simon blogs
« Reply #350 on: January 28, 2023, 06:56:07 AM »
Templates in C++

Nice talks on Youtube:

CppCon 2016: Template Normal Programming, part 1/2
CppCon 2016: Template Normal Programming, part 2/2

By Arthur O'Dwyer. A thorough explanation of C++17 templates and their language rules. The examples are straightforward, and it avoids metaprogramming examples wherever possible to keep it accessible, hence the title "Template Normal Programming".

CppCon 2014: Modern Template Metaprogramming: A Compendium, part 1/2
CppCon 2014: Modern Template Metaprogramming: A Compendium, part 2/2

By Walter E. Brown. Many short examples of type manipulation. You'll see the implementation and ideas behind standard library utilities such as  std::is_same<T, U> or std::remove_const<T>. Introduction to SFINAE.

Functors

I should revisit one of my toy C++ examples: How nice of a functor can you create, e.g., with C++ template magic, to minimize boilerplate in the usercode. Here, I mean functor in the sense of category theory, not necessarily in the sense of object that overloads operator().

The use case is: You have

template <typename T>
struct ErrorOr {
    int error;
    T value;
};


... with the unenforced rule that we should use its good value if and only if the error is 0. You have a function func: T -> U. The goal is to lift func into the world of ErrorOr: The lifted function is of type ErrorOr<T> -> ErrorOr<U> and calls func when a good T comes, and merely copies the error code when an error code comes.

The solutions will likely not be beginner-friendly, and I'm sure that other people have already found solutions that make the usercode calls look reasonably straightforward. Nonetheless, I'll keep it in mind as an exercise for myself.

-- Simon
« Last Edit: February 08, 2023, 06:02:38 AM by Simon »

Offline okmot

  • Posts: 66
    • View Profile
Re: Simon blogs
« Reply #351 on: February 17, 2023, 05:50:19 PM »
Every now and then I try to play Clones again and it's just... awful. Nothing about it feels intuitive. A Game of this nature that doesn't always allow you to pause or pausing that doesn't work correctly should be illegal. Sorry to the creator, I know they at one time were present on this forum but this game sucks.

Greetings! Nice to see Clones still being mentioned :)  The reason we limited pausing was to prevent super-human actions, because pausing makes playing levels easier and can bypass the intended challenge.  However to account for this we added a 2nd type of pausing called "Freeze Time" (default keyboard key is U) which you can use as often as you want to do super-human moves, but each Freeze Time use will incur a timeclock penalty so that players who don't Freeze Time will obtain a higher score for the leaderboard rankings, which we felt was fair.  You can even assign actions to clones when the game is paused via Freeze Time.

Here is Freeze Time in action - https://drive.google.com/file/d/1-777IGQDBmT1AWB_i_iRc4YQwNm4yTFe/view

In terms of not being intuitive, my only regret is that the "beautification" of my levels went a bit overboard I think. We hired someone and they added too many background graphics which I think make the levels a bit cluttered sometimes and hard to tell if something is land or background. I would have preferred a simpler clean look. You can however disable these graphics in the options menu: Disable Background and Sky. Oh and also the "Clones Belt" for gestures to give actions isn't practical I felt, I would have liked to make the keyboard bindings the default method - but this can also be changed in the options menu.

Otherwise I'm all ears for adjustments to include in future patches to improve the game! Multiplayer was always the focus, and I haven't played in a while so I'd be up for a match should anyone want to play.  That one "capture the star clone" map was really fun.

Offline mobius

  • Posts: 2697
  • relax.
    • View Profile
Re: Simon blogs
« Reply #352 on: February 23, 2023, 01:13:49 AM »
Every now and then I try to play Clones again and it's just... awful. Nothing about it feels intuitive. A Game of this nature that doesn't always allow you to pause or pausing that doesn't work correctly should be illegal. Sorry to the creator, I know they at one time were present on this forum but this game sucks.

Greetings! Nice to see Clones still being mentioned :)  The reason we limited pausing was to prevent super-human actions, because pausing makes playing levels easier and can bypass the intended challenge.  However to account for this we added a 2nd type of pausing called "Freeze Time" (default keyboard key is U) which you can use as often as you want to do super-human moves, but each Freeze Time use will incur a timeclock penalty so that players who don't Freeze Time will obtain a higher score for the leaderboard rankings, which we felt was fair.  You can even assign actions to clones when the game is paused via Freeze Time.

Here is Freeze Time in action - https://drive.google.com/file/d/1-777IGQDBmT1AWB_i_iRc4YQwNm4yTFe/view

In terms of not being intuitive, my only regret is that the "beautification" of my levels went a bit overboard I think. We hired someone and they added too many background graphics which I think make the levels a bit cluttered sometimes and hard to tell if something is land or background. I would have preferred a simpler clean look. You can however disable these graphics in the options menu: Disable Background and Sky. Oh and also the "Clones Belt" for gestures to give actions isn't practical I felt, I would have liked to make the keyboard bindings the default method - but this can also be changed in the options menu.

Otherwise I'm all ears for adjustments to include in future patches to improve the game! Multiplayer was always the focus, and I haven't played in a while so I'd be up for a match should anyone want to play.  That one "capture the star clone" map was really fun.

ah yes now I remember vaguely, this freeze time function.... One has to wonder; why not just make pause behave this way? Why have essentially two different types of pause buttons?? Can't it do everything freeze time can, including incurring the penalty, without *failing to pause*? I get the points thing; that's just not my kind of challenge.

The other major roadblock was how you assign skills. NeoLemmix has a similar "follow lemming" feature, but as a side option. Selecting a skill then selecting the target lemming just seems to work better most of the time. Especially if you're new to the game and clones may often be spilling out in different directions suddenly you didn't intend, you want to click quickly to get them under control. From being a lemmings player this just felt totally backwards.

The other issue I can't recall very well but had something to do with physics and how clones moved around. Maybe it was just another issue of differences from being a Lemming player.
everything by me: https://www.lemmingsforums.net/index.php?topic=5982.msg96035#msg96035

"Not knowing how near the truth is, we seek it far away."
-Hakuin Ekaku

"I have seen a heap of trouble in my life, and most of it has never come to pass" - Mark Twain


Offline okmot

  • Posts: 66
    • View Profile
Re: Simon blogs
« Reply #353 on: February 23, 2023, 02:33:49 AM »
ah yes now I remember vaguely, this freeze time function.... One has to wonder; why not just make pause behave this way? Why have essentially two different types of pause buttons?? Can't it do everything freeze time can, including incurring the penalty, without *failing to pause*?

No they can't be merged [edit: well maybe :) see below], because the two pauses serve different functions. The original pause was for actual legit pausing which shouldn't incur any penalty (initial level overview, phone ringing, bathroom break, dinner burning, etc) but we found this could be abused to get higher leaderboard scores, especially on larger (wider) levels by eliminating scrolling time and morph-click accuracy, which would ultimately lead to all high-level players being forced to abuse pause just to have a chance to get the #1 spot, because it would certainly be exploited. I didn't think that was a good direction for competitive play, so we added a few seconds of "recharge" to that pause which shouldn't be an issue for regular pause use and would prevent "cheating".
However I did appreciate that exploiting pause can make the level easier and perhaps more fun for non-competitive players, and so we added "Freeze Time" to encourage that and even allowed giving morphs while time was frozen to lean into that use case. 
Although.... in thinking about it just now I wonder if we could have auto-transitioned from one to the other silently behind the scenes.. so that pausing a few seconds apart would not incur a penalty but pausing any quicker than that would. But giving morphs while paused was only allowed in one not the other so not sure.. hmm..

The other major roadblock was how you assign skills. NeoLemmix has a similar "follow lemming" feature, but as a side option. Selecting a skill then selecting the target lemming just seems to work better most of the time. Especially if you're new to the game and clones may often be spilling out in different directions suddenly you didn't intend, you want to click quickly to get them under control. From being a lemmings player this just felt totally backwards.

Yes Simon had the same thought during beta (gamma?) testing and we implemented a "Morph On Click" option in the Options menu that allows for this.  In that mode you select a morph first (keyboard or click) and then click on a clone to give the action right away.  The reason we reversed this by default was because Clones started as a multiplayer game and in that use case it's more common to want to select a single clone and then issue a bunch of morphs in quick succession, i.e. a sabotage or pathfinding clone lone wolf, possibly wearing a cool decoration :)  Also by selecting the clone first you can be sure which clone you are going to give the action to, which can be important due to there being dark clones and light clones, "fistfight" game mode, or clones with 2x speed, or tiny/large clones or clones at different gravities (4 ways). I feel selecting the clone first enables better multiplayer success, but the option is there so everyone can choose their preference.

The other issue I can't recall very well but had something to do with physics and how clones moved around. Maybe it was just another issue of differences from being a Lemming player.

Yes the clones are a bit bulky. Originally they started out as thin grey aliens but they chubbed up when the graphics was outsourced. The Light clones are directly controllable like a mario character, but due to the pixel-perfect nature of clones/lemmings they walk a bit odd sometimes. It did take great programming effort to get them to walk on rotating/moving land but I was satisfied with the result and the flexibility of the level editor in general. Moving land can give momentum to clones or crush them allowing for a lot of level design possibilities.  I think it was CCX that created a working minesweeper mini game level, which really impressed me!

Light clone: https://drive.google.com/file/d/1Zta4JI3T0xQJN8QFVA6n-n-VzP3FWRDg/view

I was just watching my step-son play Quantum Connection the other day and we saw the leaderboards had a 5 morph solution which seemed impossible, but after some thinking we figured out how they were doing it!  It's an exploit of the entangled clones where you give a morph to a falling clone that they can't do so they queue it up, but meanwhile the entangled clone performs the morph, then you cancel the morph on the first clone before they hit the ground so they never actually use the morph so it doesn't get counted. Not sure how the top 3 players on that map figured that out but kudos to them!
The leaderboards have never been reset so it's gotten increasingly difficult over the years to get #1 on any level.

Offline Simon

  • Administrator
  • Posts: 3543
    • View Profile
    • Lix
Re: Simon blogs
« Reply #354 on: March 01, 2023, 03:39:06 AM »
Welcome back! Happy to see that you're still pondering Clones UI.

Yeah, modern Lemmings and Lix abolish execution difficulty wherever possible. Coming from this, it's natural for mobius to expect the regular pause to behave like freeze-time.

Quote
auto-transitioned from one to the other silently behind the scenes
But giving morphs while paused was only allowed in one not the other so not sure.. hmm..

Gut reaction: Yes, merging the the two pauses feels like the right direction. Penalize assignment during pause with 1 second. Still penalize rapid pausing with 1 second. Count and explain all incurred penalties on the results screen. Offer an option for whether the engine should allow such penalized input during pause, and allow it by default.

The biggest danger with this idea is that you're explaining the penalties too late, in the sense that highscore hunters stumble into new types of penalties during serious solution attempts.

-- Simon

Offline Simon

  • Administrator
  • Posts: 3543
    • View Profile
    • Lix
Re: Simon blogs
« Reply #355 on: March 07, 2023, 11:11:01 PM »
UI

Collection of bad error messages from 1996-2000. Klopt niet!

Also a link to the homepage of Isys Information Architects, the site that hosts that collection. Has several other lovely pages about bad UI.

Makes me wonder how to word the confirmation box when overwriting or deleting a Lix level:
Really delete this level? [Delete] [No]
Would it be better to use "Cancel" than "No"? Or "Keep"?

-- Simon

Offline Dullstar

  • Posts: 2065
    • View Profile
    • Leafwing Studios Website (EXTREMELY OUTDATED)
Re: Simon blogs
« Reply #356 on: March 08, 2023, 07:50:43 PM »
I think any of No, Cancel, or Delete work fine in this case.

The "Delete" option is already likely as clear as it possibly can be, and conveniently, that's the important one. From context, it's easy enough to deduce that "No" means "Don't Delete" (although I suppose "Don't Delete" is another wording you could consider; a bit lengthier, but abundantly clear), and I don't think anyone's going to say "Hmmm, I definitely don't want to delete this level, but I'm a little unsure of what "No" means here, so I'm going to push the button that says "Delete". That said, thinking about it, "No" is probably the least good option here (out of what has been presented), but least good != bad.

Offline Simon

  • Administrator
  • Posts: 3543
    • View Profile
    • Lix
Re: Simon blogs
« Reply #357 on: March 11, 2023, 01:27:01 AM »
Hmm, thanks. I think I'll put "Delete" and "Cancel". I also like "Don't Delete", but it's more text to read, and it contains the word that we don't want to do, making it hard to skim.

Lix never writes "Yes" onto a button, it always re-spells the verb. That's good already. I searched the codebase for where "No" appears, and it only appears in these two boxes:

Really delete this level? (Level name), (filename), Delete, No.
Really overwrite the level? (Level name), (filename), Overwrite, No.

I'll replace both "No" with "Cancel".

-- Simon

Offline Simon

  • Administrator
  • Posts: 3543
    • View Profile
    • Lix
Re: Simon blogs
« Reply #358 on: March 21, 2023, 09:43:55 AM »
GUI

GUI code is both very nice and annoying at the same time. Very nice because I get to define and use lots of OO interfaces and have lots of good static checking. GUI and games are excellent applications for OO.

Annoying because it's practically impossible to unittest. The logic one or two levels beneath is more meaningfully tested independently from the GUI. But the GUI should still look nice and the buttons should all call the right logic. You chance 1-2 lines of code, recompile, run the game by hand, plow through the menus, look at it, change 1-2 more lines of code, ...

Wisdom

Some wisdom from hand-rolling Lix's UI years ago that has stood the test of 7-8 years.

GUI elements are nested tree-like. A window has buttons as its children, and a button has a text label or an image as child.

Define geometry relative to the parent. I want this button to be drawn 20 units from the left edge of me (the parent), and its width shall be 1/4 of my width.

Children calculate first, then the parent calculates. Reason: The parent is interested in any state change of the children, therefore the children should already bring their own new state to the party. The children, on the other hand, don't even need to know their parent, even though they must know the parent's geometry.

If the parent has information to pass to a child, that can still happen during calculation of the parent (after the child has finished its normal calculation), and trigger more code to run in the child separately from the child's regular calculation. All of this must still happen before anybody paints to the screen, thus separate calculation and painting completely.

Callbacks are handy for buttons. Give the parent a choice whether to hook a callback to the button (in OO code, everything happens elsewhere), or whether to query the button's state (soviet style: the central government knows best). Sometimes callbacks are nicer, sometimes soviet style is nicer. As the button, offer both.

Make stuff idempotent and avoid unnecessaary work, e.g., extra painting if it's already painted as you want. Push this logic down into the childmost GUI element. As a parent, don't { ask your button if it's already on, and if not, set it on }. The parent should write the simplest possible code: { set the button on }. The parent should trust that the button doesn't do unnecessary work, i.e., the parent should trust that the button is implemented roughly like this:

void Button::switchOn()
{
    if already on {
        return;
    }
    _on = true;
    require to be repainted (scheduled for the next round of painting);
    call your callbacks (that react to you getting switched on);
}


Outside of GUI, you rarely want to write setters, you'd usually prefer immutable objects that you discard and replace. But in GUI, setter-like methods are common and feel correct. As above, they tend to have more logic than setting one field.

Parent paints firsts, then the childrens paint. This is the inverse order in which they're calculated. Reason: You want the text label in front of the button, not behind the button (where the button's flat surface would obscure it entirely). You want the button in front of the window.

When a parent must repaint itself, all children must recursively repaint.

-- Simon
« Last Edit: March 21, 2023, 10:27:39 AM by Simon »