Simon blogs

Started by Simon, October 18, 2015, 06:05:44 AM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

namida

NeoLemmix previously (in fact, the current stable version still supports it, but experimental does not and there are no plans to restore this support) supported a feature where a level could define a unique skillset / stats, while referring to another level for the layout.

I'm pretty sure my packs are the only ones that ever actually used it, rather than just having hard copies of the levels. Since it's not widely used, and complicated the code, that's why it isn't being supported anymore. Instead, the editor now has a feature that serves much the same purpose - it loads a layout from another LVL file, without loading the stats from that level, into the currently loaded level. I don't know if this is being used either; at least one person has indicated that they prefer to (upon modifying the source level) simply Save As the level and re-do the different stats / etc.
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)

Simon

#16
Rant topics that I never got around to rant about

Repeats: Levels with the same terrain as another level. There is lots of fire here. I have several arguments flying around and never wrote them down.

<geoo> SimonNa: where's your rant topic about repeats? :P
<SimonNa> I wrote about one issue, the need to keep otherwise unrelated data in sync manually. That didn't ring with anyone
<geoo> I actually agree with most of your points, I just reject your conclusion


Drawing alongside writing: I am writing a post, and I want to explain something visual. Ideally, I'd sketch with my hand right inside the post. The cumbersome solution is to open a painting program, draw a picture, then upload or attach. Way too cumbersome, and fragile. The image should be data right in the code text, and I should be able to draw on the screen somehow. Technology sucks here.

Generate subforum from topic: I have a topic to split up, but I don't want to generate multiple topics on the existing board. I want these to belong together clearly. Instead of forum topics, I want directories. A directory contains either exactly one linear discussion (screw tree discussions, they suck, everybody replies wrong) or more directories.

Everybody should split and merge: When you have >= 100 posts, you can move and split and merge forum topics to your heart's delight. Like Stackoverflow. The forum software should version everything, which it doesn't right now.

Coins should be square: Then they don't roll under the sofa. And you don't need a 20-cent piece when there exists a 10-cent piece. You learn that from every site that teaches choosing poker chip denominations. There should be a 1-unit piece, this is the smallest unit that you can trade with cash. Then a 4-unit piece, a 16-unit piece, a 64-unit piece, and so on.

Functions compose from left to right: Instead of y = f(x), write y = xf. Then h(g(f(x))) becomes xfgh. Vectors are row-vectors by default, then vM makes sense for a matrix M. Matrix multiplication can stay like it is. Everything becomes a Unix pipe! Stuff gets processed in reading order!

You can treat a piece of data, x in the above examples, as a function from the one-point set into your data domain. Then everything is a function. Everything is a set, everything is an object, everything is a file, everything is a function.

-- Simon

Simon

#17
My favorite writer on the net is still cbloom.
  • Nowadays, the good things land on cbloom rambles: When I go to my editor and click on the "X" button, you don't pop up "this file has changed on disk do you want to reload it?". You just fucking close.
  • His classic rant that I've linked before, Fucking fuck the fucking web: Managers are hesitant to ever admit a mistake or cut a huge feature or redo work, because it reflects badly on them. That's terrible. It means that broken awful shit gets shipped just because they politically have to keep insisting "we did a great job".
But I've found Bob Nystrom's StuffWithStuff. This focuses purely on software design and language features. Some gems:
  • Higher-Order Macros in C++, let a macro write a list of code-generating macro calls.
  • The Impoliteness of Overriding Methods: To guarantee that overridden methods work well with your base class, you can mark the base method final, provide a second virtual method to override, and call the virtual method within the final method. This doesn't scale well with deeper inheritance. BETA was a niche language that made this pattern a core language feature: The base methods provided extension points within themselves, or were final.
  • What color is your function? This article made it to reddit/programming and hackernews last year. Languages lack abstractions over mixing sync and async function calls. If you don't want your application to wait on costly I/O, you must jump through too many hoops.

-- Simon

ccexplore

Wasn't it Simon who once complained about bad topic titles?  I think it's time we change "open source != level design" to something more accurately reflecting the current trends of this thread. ;P

==============

I'll see if I have time to actually and carefully read through Bob's gems.  My gut reaction though is:  "really? advocating for C++ macros?  um..." (then again, it's possible the article is more just technical showoff of the crazy things you could do with macros in C++, not necessarily that you want to use them widely).  I totally get where he's coming from with the sync/async thing, but can't help but suspect that there may be an unintended side benefit of not having completely identical syntax, in that it makes one more aware of a function being async, which I suspect can be a good awareness to have when you need to reason over code.

Simon

Topic name: Yeah, hm.

It's a blog, except that it's on Lemmings Forums and not on its own site. The benefit is that interesting people will read it here. A more permanent solution depends on how I handle asdf-down.

-- Simon

Simon

#20
Board games with edge cases: I googled for stalemates in Shogi. Stalemates never happen in normal play, but they're a lovely edge case. Game rules should not have holes. The intuitive result is that the stalemated player loses, and I'm happy that it's the customary result, too.

I found a forum discussion on stalemates in Shogi on Little Golem, a turn-based server. The discussion produced the answers I had been looking for. But I was even more happy about this quote:

Anyone who sees the world in terms of clean logic has to be mystified and bewildered by many of the rules in popular board games. Especially ancient board games, like Go, that have suffered thousands of years of pollution from meddling humans... :-/ -- Darse Billings

Yes! When you have surprising edge cases in games, try to make rules as simple as possible while trying to fix them. Can you make the corner case part of the normal cases?

Empathy: Little Golem runs a daily game, Empathy, which is similar to our Quizmaster's Family Feud.
  • The master presents a single word, today's expression.
  • Every player private-messages the master with 10 different words. These 10 words should be in close association with today's expression, but players are free to send anything.
  • All answers are revealed. For every word you send in, you get 1 point per player who sent in that same word. Singulars and plurals of the same word count as a same word.
-- Simon

ccexplore

Quote from: Simon on August 30, 2016, 10:59:50 AMAnyone who sees the world in terms of clean logic has to be mystified and bewildered by many of the rules in popular board games. Especially ancient board games, like Go, that have suffered thousands of years of pollution from meddling humans... :-/ -- Darse Billings

Too bad I don't know the exact rules of Go to really understand this.  I was always under the impression that Go has simpler rules given the much lower number of different types of pieces with different move mechanics.  Chess even has its share of special moves like castling, pawn promotion and en passant etc. that are just part of the game, you can't blame them on edge cases.  Sounds like maybe Go is more prone to stalement-like conditions that require layers of special rules to deal with?

"Pollution from meddling humans" isn't necessarily a bad thing, or at least it can often be a necessary tradeoff.  One thing that came to mind are the mechanics we introduced to lix to make the miner more resilient to canceling.  From the rules perspective, those tweaks are not very clean at all, but it seems the "meddling" is called for based on issues encountered in the actual gameplay experience.  In many ways it's like patching a level to prevent backroutes:  it keeps the level more interesting by eliminating otherwise legal but trivial solutions, but often at the cost of complicating the level with unsightly traps and other such elements.

Simon

#22
Quote from: ccexplore on August 30, 2016, 07:28:51 PM
mechanics we introduced to lix to make the miner more resilient to canceling.  From the rules perspective, those tweaks are not very clean at all, but it seems the "meddling" is called for based on issues encountered in the actual gameplay experience.

Yes, miner-anti-shock fixes single-cancelling: If you have a working miner, there are lems in her tunnel, you could have canceled the working miner by assigning miner to a backwards walker in the tunnel tip. We believe that miner-anti-shock is free of unwelcome side effects. So far, it turned out okay.

Miner-anti-shock has complicated the code. We have spent our one chance to introduce a complicated fix: If we ever have to fix another miner behavior, we must check the two complicated fixes for a ton of interactions, or find a complicated fix that covers both cases.

QuoteIn many ways it's like patching a level to prevent backroutes:  it keeps the level more interesting by eliminating otherwise legal but trivial solutions, but often at the cost of complicating the level with unsightly traps and other such elements.

Yes, extra rules to patch holes are like unsightly traps and steel.

Extra game rules can be more severe, because unlike traps and steel, you must memorize them. Learning the game becomes more expensive. Some extra rules distract from beautiful pattern finding, because they introduce exceptions that feel arbitrary.

QuoteToo bad I don't know the exact rules of Go to really understand this.  I was always under the impression that Go has simpler rules given the much lower number of different types of pieces with different move mechanics.

Go can be scored in different ways: Area scoring and territory scoring.

Area scoring is simpler, more beginner-friendly, and almost every computer program uses it. You get 1 point for each living stone, and 1 point for each node of territory. If you play unnecessary moves within your own territory, you don't lose anything: You have 1 more living stone and 1 fewer territory.

To resolve difficult positions, near the end of the game, you can play them out at no cost. Normally, players agree what is alive and dead. Playing out everything is rare, that's to settle disagreements. You may resume play and capture every dead stone.

Territory scoring gives 1 point for each stone you have captured, and 1 point for each node of territory. If you now play in your own territory, you lose a point.

If both players agree what stones are dead, they are removed after play at no cost. But if the players don't agree, you can't capture for free, because playing in your territory costs 1 point. You would really like to declare stones dead that you could capture unconditionally.

This demands that the rules have an understanding of life and death -- the property of stones to be immune to capture against best play. Japanese territory rules demand that you copy the local position to a second board, analyze it there, and use the result to declare stones alive or dead on the first board.

Here's the next can of worms: What is local? The rules must define that. Local positions play out differently than their inclusion in global positions if there is a ko.

The alternative, requiring all dead stones to be captured on the original board, would make plays into the other guy's territory attractive: You play one stone, but it takes 4 moves to capture it, so this play is worth +3 for you. This is unwanted, and thus has lead to such complicated rules for agreement. The obvious solution would have been area scoring. On most positions, they produce the same winner anyway.

-- Simon

Simon

#23
I was bored this morning and looked for bugs in the NL assignment.

I didn't want to program, because that's hard, and didn't want to work on math, because that's hard, and I didn't want to play or design levels, because that's abstrusely hard. Yet I needed intellectual stimulation, and assignment bugs were it. Level backrouting and bug hunting scratch the exact same itch -- finding assumptions that clash with the real world, and building a better mental model from black-box testing.

It's not super useful to debug the assignment: I fished for bugs in code that will be redesigned anyway within the next weeks. Maybe others read the bug reports and treat it as warnings. But the highly artificial ways to trigger a bug make the bug unlikely in the wild. I found Desync on same-frame RR & assignment purely for my personal enjoyment.

The point is not to boast Lix over NL. If I had that goal, I would go develop and showcase my own results, not stir action on the NL board.

Zendo should be similar, but it's not like level backrouting, rather like level solving. In Zendo, I'm trying to discover the designed rule, and fight my own assumptions. But even higher than the beautiful, I value the strange. In backrouting and bug hunting, I find places that still need a design.

-- Simon

Simon

#24
The level is the unit of culture

In singleplayer Lemmings, the level is the most important piece of culture. Everything else must support that, or it has a problem.

Packs and ranks are sets of levels, plus flowery extras: A meaningful order of levels, or cute rank names. Everybody is busy worrying about rank names, or sorting their levels. Icho worries even about a balanced distribution of graphic sets among the ranks.

That's okay, designers can worry about that, and strive for these extra goals. Still, I get a set of levels. I can enjoy the flowery extras, but aren't forced to pay attention to them.

Locked levels or hidden levels get in the way. They remove my random access of levels. It's a designed experience, sure, but doesn't allow the operations that I routinely invoke on a set of levels. I'm happy that the culture has moved away from locked levels.

Beware the bookkeeping

Menu screens, bookkeeping features, etc., all these are okay if they don't get in the way of level playing. Lemmini took notoriously long to restart a level, you had to go through 2 screens. If restart is at least moderately common, design out of existence these screens.

I tried to go too far with Lix, I tried to remove the end-of-game dialog altogether. Instead, the level went into a special kind of pause at end of game, didn't display any message, and didn't pop in any extra UI. The best approach is to pop in UI that's not modal, i.e., that doesn't take away control from the normal game UI. I have settled on keeping all game hotkeys alive in the end-of-game dialog, that's at least an intermediate step towards non-modality.

It's all about how to maximize time designing and playing levels, and to minimize bureaucracy outside of levels.

-- Simon

Simon

#25
Interesting voicechat with geoo yesterday.

Definition (topographic prominence). Let M be a manifold and f a real-valued continuous function on M. Let x be a point of M that is a local maximum, but not a global maximum. Consider the set of all paths w on M that start at x and end at any higher maximum of f than x. For each such path w, we're interested in the minimum value of f along it, min(w) := inf { f(y) : y is in the image of w }. We define the topographic prominence of x as
inf { f(x) - min(w) : w is a path from x to a higher summit }.

Equivalent definition on wikipedia: The topographic prominence of a summit x is the height of the summit at x above x's lowest encircling contour line that doesn't encircle a higher summit than x.

Example 1. Consider the height f of a mountain range on a one-dimensional planet surface M.



The highest peak is special, we don't consider it. Every other peak has a vertical arrow below it that describes its topographic prominence.

Example 2. Consider a little spike on Mount Everest, 10 meters away from the highest summit. Even though this spike is very high absolutely, it has low topographic prominence. There is a path from the spike to the summit that goes down just a little, across 10 meters, and up to the highest summit. The "down just a little" gives the spike low topographic prominence.

Trivia question. We drain the earth of all water, making the mountains under the ocean visible. Our two-dimensional manifold M is the surface of the drained earth. The function f on M measures the height of the mountains.

The highest summit is Mount Everest. Not considering Mount Everest because it's the global maximum, what are the two points on the drained earth with highest topographic prominence?

Solution
The next-prominent peak is Mauna Kea, Hawaii. The volcano is over 4 km high, and the water around it is over 4 km deep. To get to anything higher in America or Asia, you must go down over 9 km and across the Pacific.

After that comes the highest mountain in the Andes. You get from there to the Himalaya via the Bering strait. The strait is shallow, but everything higher is in Asia already, not as prominent.

-- Simon

Simon

#26
The previous post left a trivia question about topographic prominence. I have added the solution to that post.

Simon rants about all the engines

Lemmini ate your files. Superlemmini (SL), because it's more super, creates files instead: SL generates lots of empty directories. Nepster is going to file an issue tomorrow. There is never a reason to create empty directories if you won't put anything inside. When you create a file in a nonexistant dir, create all parent directories along with the file.

NL and SL fade between screens, but don't load anything during this time. Bad, remove the fading. Fading is for music that runs alongside, not for the main content which should pop in ASAP. I wrote about this in a post above already.

Depends on the JVM.

NL has the disarmer that is full of corner cases and makes traps depend on the terrain. The disarmer is a boring key skill: Like a key for a door, it allows access to an area for you, and alters the landscape without flexibility in application. It's not an exciting swiss-army knife, like builders that can fulfil 3 objectives at once. Unlike most key skills such as the floater, the disarmer brings inconsistency and lots of arbitrary design decisions. The worst of all worlds.

The obvious cure is to cull the disarmer, then bomb or bash underneath the trap. Awesome disabled trap, and the idea fits 100 % into what the game is about: Alter the terrain to do things.

Spoiler

The NL editor doesn't fetch Lemmini styles and doesn't open Arty's levels. Arty is confused and "Nothing's working and I have to meet with my lab partner now" even when Nepster was there all the time for tech support. Good luck convincing Prince Jamie to develop for NL with this user experience.

Arty should put his levels under version control. Everybody should put their levels under version control! If it's creative work, version-control.

Here is my problem: teaching regular people to use version control is impossible. It just can't be done in this universe. There is just no possible way a regular Joe can be convinced to start using Git. You know how I know? Because it is fucking near impossible to teach programmers to use it. -- Terminally Incoherent

Lix has too many skills and is intimidating. The imploder is boring, but seems necessary, it's exciting to sacrifice lems in a level design. Too many movement skills. Singleplayer shouldn't have runner, walker, or floater. Multiplayer needs the walker and jumper, but the only reason is "I tried both and this is more fun." I would still remove the runner and the floater, if people let me. :> mobius likes the runner, he likes the movement skills in general, but I don't.

Maybe the blocker should only block your own lems, and we remove the walker. Blocking other people's lems is annoying and not exciting. But we get an inconsistency: Blockers ignore enemy lems, batters bat enemy lems.

Walker skill assignments turn, or don't turn, depends on the previous activity. Bad! Skills should do similar things all the time! I want to cull the walker skill. Help me support this idea and barge forward into the sky of prisine design! L3's direct control sucks when your game isn't about skill pickups.

I haven't worked on D Lix in two weeks, I've been a lazy bum. The necessary work until the first networking tests is forseeable. Now that it's obvious how to do it, I don't need to do it, everybody could do it. >_>

Levels should be small. Or the interface should allow replay rebasing, where you insert skills into a running replay and modify the replay's tail accordingly, without cutting off the tail. Probably both, small levels and rebasing. Rebasing for replays is dangerous, the computer could easily try to be smarter than the user. And the UI that this needs. X-(

Nuke in singleplayer should not be part of the puzzle. The planned multiplayer concede-nuke closes exits in multiplayer when overtime runs out, then everybody explodes. Singleplayer nuke, therefore, should close exits, then everybody explodes. We can consider this to be a single rule for the nuke, because all singleplayer levels and selected multiplayer levels have no overtime.

Screw the 3rd-person-singular-s, it be obvious what the verb belong to, it introduce maintenance in part of the sentence that didn't change.

-- Simon

NaOH

Quote from: Simon on August 19, 2016, 09:18:47 AM
Functions compose from left to right: Instead of y = f(x), write y = xf. Then h(g(f(x))) becomes xfgh. Vectors are row-vectors by default, then vM makes sense for a matrix M. Matrix multiplication can stay like it is. Everything becomes a Unix pipe! Stuff gets processed in reading order!

You can treat a piece of data, x in the above examples, as a function from the one-point set into your data domain. Then everything is a function. Everything is a set, everything is an object, everything is a file, everything is a function.
-- Simon

This has been bugging me since you posted it. If you put a transpose sign after everything, then you can solve a lot of problems, while not breaking any conventions:


  • All vectors are column vectors by default
  • Matrices now index correctly, with x and y not being flipped weirdly. A^T_{x,y} = X_{y,x}
  • Matrices operate on vectors in front of them, left-to-right. x^TA^T = (Ax)^T

NaOH

About your solution:

Spoiler

The volcano has a protrusion of 8 km (above ocean ground), shouldn't the Andes beat this with a protrusion of 4 + 6 = 10 km?

Simon

Quote from: NaOH on October 16, 2016, 02:29:41 AM
About your solution:

How do you define protrusion of a peak? Height difference of the peak and the surrounding ocean floor? What's the exact height of the floor then?

Spoiler
The Andes are higher than Mauna Kea. Nonetheless, they have lower topographic significance, because their connection to the Himalaya goes along a higher route. The path from the Andes goes through the shallow Bering strait. Any path from Mauna Kea to anything outside Hawaii goes across the Pacific floor, which is much deeper than the Bering strait.

-- Simon