Disorganized Dev Diary for Never Gives Up Her Dead (Now released!)

I’ve been working on this game on and off for the last year, and I’m 73% complete. I’ve been making little updates on a different group that recently got shut down, so I’m going to post on here instead (unless it annoys someone! Then I’ll go somewhere quite like Twitter or something.

Edit: This game is now released!

This is a spoiler heavy document, and it’s mostly ‘I’m glad I got such and such to work’.

I’m currently working on my last ‘normal’ area. The game is split into 10 dimensions, of which 8 are basically ifcomp-size (i.e. 2 hr long) games that are almost entirely independent from the others, 1 more dimension that is integrated with all the others, and then the finale, which is separate.

Areas I’ve done so far include (mild spoilers) a haunted house with traditional gameplay (the original intent was to mimic Garry Francis’ style, although I diverged from that later), a murder mystery using my conversation system from Color the Truth, a wax museum escape room, a horror game using spells, a combat arena commanding robot squadrons, a slice-of-life nature area with journal pages, and a zoo. My current area is focused on math and physics.

Anyway, with that background, here’s my first entry. When I was doing a Let’s Read of the Inform 7 documentation, I was amused at the fact that the inverse hyperbolic tangent is built into Inform 7, and I decided to design a puzzle requiring it. It shows up in hyperbolic geometry, my PhD area, so I’m loading in a bunch of geometry stuff in this section. To help players out, I made a calculator, and I’m posting the code below:

(note: some parts are placeholders, like the description)

Calculator Code
The busted-calculator is on the shop-stand. Understand "busted" or "calculator" or "display" as the busted-calculator. The printed name of the busted-calculator is "busted calculator". The price of the busted-calculator is ET50.00. The description of the busted-calculator is "This is a scientific calculator, with the regular buttons for numbers and the decimal point. However, the keys for exponential and logarithmic functions are missing, along with others. Instead, all that are available are SIN, COS, TAN, SINH, COSH, and TANH. There is also an INVERSE toggle.

The display currently says '[error-display]'."

The number-keys are a plural-named part of the busted-calculator. Understand "number" or "key" or "keys" or "decimal" or "point" as the number-keys. The printed name of the number-keys is "number keys". 

Instead of pushing the number-keys:
	say "Instead of pushing individual keys for numbers, you can simply ENTER the entire number. For instance, you can ENTER 3.1415."

A calculator-button is a kind of thing. Understand "key" or "calculator key" as a calculator-button. A calculator-button is usually privately-named. The description of a calculator-button is usually "This calculator key (fortunately not busted) is labelled '[button-text of the item described]'."

When play begins:
	now every calculator-button is part of the busted-calculator.

A calculator-button has some text called the button-text. Understand the button-text property as describing a calculator-button. The printed name of a calculator-button is usually "key". 

Before printing the name of a calculator-button (called currentcalc):
	let temptext be button-text of currentcalc;
	say "[temptext in upper case] ";

The clear-button is a calculator-button. The button-text of clear-button is "CLEAR".
The sin-button is a calculator-button. The button-text of sin-button is "sin".
The cos-button is a calculator-button. The button-text of cos-button is "cos".
The tan-button is a calculator-button. The button-text of tan-button is "tan".
The sinh-button is a calculator-button. The button-text of sinh-button is "sinh".
The cosh-button is a calculator-button. The button-text of cosh-button is "cosh".
The tanh-button is a calculator-button. The button-text of tanh-button is "tanh".
The inv-toggle is part of the busted-calculator. The printed name of the inv-toggle is "INVERSE toggle". Understand "inverse" or "toggle" or "inv" as the inv-toggle.

An arithmetic-button is a kind of calculator-button. 

The plus-button is an arithmetic-button. The button-text of the plus-button is "PLUS".
The minus-button is an arithmetic-button. The button-text of the minus-button is "MINUS".
The times-button is an arithmetic-button. The button-text of the times-button is "TIMES".
The divide-button is an arithmetic-button. The button-text of the divide-button is "DIVIDE".

The busted-calculator can be inverted or not inverted. The busted-calculator is not inverted.

Instead of pushing the inv-toggle:
	if the busted-calculator is not inverted:
		now the busted-calculator is inverted;
		say "You push [the inv-toggle], and it sinks down, staying there.";
	otherwise if the busted-calculator is inverted:
		now the busted-calculator is not inverted;
		say "You push [the inv-toggle], and it pops back up.";

Last-button is a thing that varies. Last-button is clear-button.

Instead pushing a calculator-button:
	now last-button is the noun;
	say "You press [the noun]. ";
	if last-button is clear-button:
		now calc-display is 0.0;		
	otherwise if the busted-calculator is not inverted:
		if last-button is sin-button:
			now calc-display is sine of calc-display;
		if last-button is cos-button:
			now calc-display is cosine of calc-display;
		if last-button is tan-button:
			now calc-display is tangent of calc-display;
		if last-button is sinh-button:
			now calc-display is hyperbolic sine of calc-display;
		if last-button is cosh-button:
			now calc-display is hyperbolic cosine of calc-display;
		if last-button is tanh-button:
			now calc-display is hyperbolic tangent of calc-display;
	otherwise if the busted-calculator is inverted:
		if last-button is sin-button:
			now calc-display is arcsine of calc-display;
		if last-button is cos-button:
			now calc-display is arccosine of calc-display;
		if last-button is tan-button:
			now calc-display is arctangent of calc-display;
		if last-button is sinh-button:
			now calc-display is hyperbolic arcsine of calc-display;
		if last-button is cosh-button:
			now calc-display is hyperbolic arccosine of calc-display;
		if last-button is tanh-button:
			now calc-display is hyperbolic arctangent of calc-display;
	if last-button is an arithmetic-button:
		if calc-display is nonexistent:
			say "ERROR";
		otherwise:
			say "The display says ENTER SECOND NUMBER.";
	otherwise:
		say "Now the display says '[error-display]'."

To say error-display:
	if calc-display is nonexistent:
		say "ERROR";
	otherwise if last-button is an arithmetic-button:
		say "ENTER SECOND NUMBER";
	otherwise:
		say calc-display;
	
The calc-display is a real number that varies. The calc-display is 0.0000.

Calcinputting is an action applying to a real number and one thing. Understand "type [a real number] on/in/onto/into [busted-calculator]" or "enter [a real number] on/in/onto/into [busted-calculator]" or "push [a real number] on/in/onto/into [busted-calculator]" or "input [a real number] on/in/onto/into [busted-calculator]" as calcinputting when the busted-calculator is held by the player.

Carry out calcinputting:
	if last-button is an arithmetic-button:
		if calc-display is nonexistent:
			say "You type your number into the calculator, but it still says 'ERROR'.";
		otherwise:
			let tempnum be the real number understood;
			if last-button is  plus-button:
				now calc-display is calc-display plus tempnum;
			if last-button is  minus-button:
				now calc-display is calc-display minus tempnum;
			if last-button is  times-button:
				now calc-display is calc-display multiplied by tempnum;
			if last-button is divide-button:
				now calc-display is calc-display divided by tempnum;
			now last-button is clear-button;
			say "You type your number into the calculator. It now displays [error-display].";
	otherwise:
		say "You type your number into the calculator. It now displays [the real number understood].";
		now the calc-display is the real number understood;
23 Likes

Okay, so like I said, I’m using this thread to put things I was putting in the chat thing before. So feel free to mute this if it gets annoying!

I’m trying to use a lot of the physics stuff Emily Short has in the examples. So right now, I’m looking at a way to use Witnessed 1 (which uses a depleting battery) and Witnessed 2 (which uses a meter to detect how close a ghost is).

I don’t have zombie states/fail states in this game, so I need a way to recharge batteries (so I’m letting the original shop you buy them in recharge them). But how can you use the meter?

One idea I had is a metal detector. But then you’d just use it in each room, eventually finding the one.

So instead I was thinking it’d be fun to do something like minesweeper. Have a room with a grid with the meter getting stronger in some places and less in others, and you can mark the ‘bad ones’. Once you correctly mark all ‘bad ones’ it’s over.

I could see it working, but I can’t see a good way to penalize hitting ‘the wrong spot’ with my current constraints, because there’s no dying in this game, so players could retry endlessly, and I’ve chosen to eschew randomization (for a variety of reasons, mostly so walkthroughs are consistent).

Although typing this out, I guess I could just not give feedback until the player is confident they’ve marked every ‘mine’. Then they check all of them at once; that actually could work, since even with just 9 spots there are 512 possibilities and they can’t all be lawnmowered.

Edit: Actually I keep saying ‘mute the thread’ but can you actually hide a thread in Discourse?

Editedit: When I started plotting out dimensions, I had rifts opening around the ship and near each one, some creature came out the rift to take something important from one of your crewmates.

Since this is the last area, I thought it might be fun to have the creatures give you something instead of taking away; since this area is an archaelogical ‘dig’ of world monuments (floating in space), it could be a journal detailing notes towards the prize at the bottom (like the Indiana Jones journal).

5 Likes

Yeah, I would just do that – seems good enough to encourage people to engage with the actual puzzle, and if they decide to brute force it instead that’s on them.

I’ve never used it myself, but there’s a little notifications selector right by the reply button and one of the options is “mute”, which means you don’t get notifications and the thread won’t pop up for you in the “latest” display, per the tooltips.

4 Likes

Very neat!

A couple of questions:

I’m wondering why you did it this way?

Every calculator-button is part of the busted-calculator.

seems to work for me.

Also, as a small convenience, instead of

Before printing the name of a calculator-button (called currentcalc):
	let temptext be button-text of currentcalc;
	say "[temptext in upper case] ";

you can just write:

Before printing the name of a calculator-button:
	say "[button-text in upper case] ";

([button-text of the item described in upper case] is inferred)

4 Likes

I do it all the time. Works as advertised.

4 Likes

Thanks for the tips! These are all things I just wasn’t confident about. ‘Every’ is something I’ve only started using in the last month or two, and when you can refer to properties without stating the name of the object is something I always have to guess at.

Thanks for the adjustments!

2 Likes

If you want to save your fingers some more, and make your code read slightly easier, you can also write, for example:

The clear-button is a calculator-button with button-text "CLEAR".
4 Likes

That one I may not change. This is an open-source project, and if you saw the code, you’d see that that inefficiency is quite rife in the entire project (this is my sunk cost fallacy rule):

However, I will definitely use that trick in the future!

7 Likes

In Inform, there’s a rule in the settings that makes all testing random stuff always give the same output. This works sometimes (like a password) but not other times (like a dice roll). This makes it easy for you. The walkthroughs when other people test - now there I don’t know if they keep that. Maybe it’s solely while testing.

3 Likes

When I made test scripts for playtesters to use, I just made dummy verbs that skipped the randomness altogether.

3 Likes

Randomness is one of those things that can be used well, but is absolutely full of traps for the unwary. In the specific sense that there are a lot of solutions that suggest themselves that are a) easy to implement and b) almost certainly not what you actually want.

For example, a lot of old console RPGs (like the early Final Fantasy games) have random encounters. And you can see the designers were thinking that a random encounter should occur roughly (to pick a number) every ten steps. So every step they pick a number between one and ten and if it’s one, there’s a random encounter. Which means that it’s possible to have runs where there’s an encounter literally every step. Which is not what anyone wants. So a better approach would be something like: at the start of the game or after an encounter, pick a number between one and five, add five, and have an encounter after that many steps (or something more elaborate if you actually care about the shape of the distribution).

This sort of thing is pretty well explored in procgen-heavy gamedev these days (so in things like roguelike design), but it’s one of those things where you’re unlikely to encounter all the tools and theory that make it easy to work with if you haven’t specifically done a deep dive on the subject.

6 Likes

Super frustrating. Thank you for providing insight here.

1 Like

I’m now working on a fire-based puzzle. This dimension really pulls on a lot of the Inform examples, because I was so impressed with how much work into them and haven’t seen a lot of games use the more complex ones. Some examples become their own dimension (like the Clark Gable example became the ‘robot army that you command’ dimension), and some dimensions don’t use any examples at all, but since this is my last normal dimension I wanted to pull out all the complex ones, especially those related to math and physics.

Anyway, I’m using two fire examples, one about matches and lighting things on fire (Example 418, providing a complex way of starting fires) and one about fire spreading and things taking a while to burn and objects in containers being revealed and such (Example 401, In Fire or Flood).

For sure, I’m sandboxing this area. Being able to carry matches around and light things on fire would seriously mess up the rest of the game (especially the wooden cabin in a dry forest with a window made of oiled paper!). So I’m putting it in the context of a demolition site that has forcefields keeping outside items out and flammable items in (these forcefields exist in other areas of the game, like the weapons dimension, so it’s not a stretch here). For story purposes this is set in a copy of the Sydney Opera House floating on an asteroid that’s really old and crumbling.

Fire is pretty irreversible, so I’m of two minds here. One is to have something really big you have to burn, and it needs sustained heat, and there are a ton of supplies around (wooden posts, old fliers, seats and benches), so you just have an inexhaustible supply of stuff to build better and better fires with. A variant of this would include a nearby room with water that’s dripping on the big thing (since Sidney Opera House has two main halls, one could be water and the other fire), so you have to stop the leak, dry out the thing and then burn it.

The other option would be to just have a very simple puzzle involving burning something small (like a desk holding a metal object you need) but have the fire spread wildly out of control in an amusing fashion until everything collapses around you, leaving you in a burnt-out shell. There wouldn’t really be a puzzle, just a kind of action scene.

(Note: I welcome any comments, but don’t feel like you have to! Often I figure out exactly what I want just from typing this stuff out. Right now I’m on the fence, though, so I’m going to compile a version with just the test objects from the examples and see how it plays out).

Edit:

This is what the current version does:

Summary
>gonear matches
Concert Hall
You can go north to leave the concert hall or west to enter the opera theater.

On the desk is a flyer.

You can also see two matches, a matchbox (in which are five matches) and a box (in which is a shroud of Laertes) here.

>light flyer
(with the match)
(first taking and lighting the match)
You light the flyer with the flaming match.

>z
You wait, taking your time.

Flames engulf the desk.

The flaming flyer burns away. 

>z
You wait, taking your time.

A spark from the flaming desk catches the box!

The match goes out.

>z
You wait, taking your time.

A spark from the flaming desk catches the shroud of Laertes!

>z
You wait, taking your time.

>z
You wait, taking your time.

>l
Concert Hall
You can go north to leave the concert hall or west to enter the opera theater.

You can see a match, a matchbox (in which are five matches) and a flaming box (in which is a flaming shroud of Laertes) here.

The flaming desk burns away. 

>z
You wait, taking your time.

>l
Concert Hall
You can go north to leave the concert hall or west to enter the opera theater.

You can see a match, a matchbox (in which are five matches) and a flaming box (in which is a flaming shroud of Laertes) here.

The flaming box burns away, leaving a flaming shroud of Laertes and a metal hinge behind. 

>

I really like this! I think it needs more descriptions every turn of what’s on fire; right now it only gives messages when looking or when something finally burns away. And of course I need to make my own items and not just the test items the game has.

Editedit: I’d also like the final area to incorporate parts of each dimension. Maybe something could be on fire?

7 Likes

Accidentally burning down the Sydney Opera House seems fun to me (and in the game!)

4 Likes

As an Australian, I have to say “OI MATE!”

5 Likes

My apologies:

Summary
>z
You wait, taking your time.

A flaming wooden door, flaming timber panels, a flaming oak desk, a flaming box, a flaming safety manual, a flaming concert-roof and a flaming drawer are on fire.

>z
You wait, taking your time.

A flaming wooden door, flaming timber panels, a flaming oak desk, a flaming box, a flaming safety manual, a flaming concert-roof and a flaming drawer are on fire.

>z
You wait, taking your time.

The flaming oak desk burns away, leaving a flaming drawer behind. The flaming safety manual burns away. 

A flaming drawer, a flaming wooden door, flaming timber panels, a flaming box and a flaming concert-roof are on fire.

>z
You wait, taking your time.

The flaming drawer burns away, leaving four field-dampers behind. 

A flaming wooden door, flaming timber panels, a flaming box and a flaming concert-roof are on fire.

>z
You wait, taking your time.

FIX THIS LATER The opera theater burns down.

A flaming wooden door, flaming timber panels, a flaming box and a flaming concert-roof are on fire.

>

(But don’t worry! This was an old fake opera house, and there is a newer replacement Sidney Opera House that is much better than the old one: Ikea "Lamp" Commercial - Hi Res - YouTube) It definitely fares better than the Statue of Liberty and Eiffel tower, which are just full of overpriced shops, coin-operated machines and commercialism.

I’m almost done with all the basic puzzles for this dimension but in a very skeleton-y form, and then have to flesh them all out (like right now the Taj Mahal just has a giant pile of cash sitting in it that I need to disperse). I just want to get in something involving momentum or angular momentum. The overall layout is vertical, with floating asteroids at different ‘strata’ moving from Stonehenge (the most recently abandoned) to the Sydney Opera House (the most ancient replica). A lot of times two islands are at the same height. It’d be nice to have a puzzle involving inelastic collision or angular momentum. I’ve thought about having a harpoon on one spinning planetoid that shoots to another one (then they both spin much slower around their new center of mass), but that’s not much of a puzzle. I could also have a cannon you fire off into the void that slowly changes the angular momentum, and you have to fire differing masses in different directions to slow it down to 0.

4 Likes

Hmm, for angular momentum you could have a puzzle where you need to spin something really quickly (maybe a drill assembly?) so you need to move all the mass inward and thereby increase the speed.

The reason I think of this is a physics laserdisc I watched in high school that had astronauts doing cool angular momentum tricks while in orbit - one had a guy set himself spinning, then slow down by extending his limbs and speed up by pulling them in. As we were watching we noticed something odd blip onto the screen, and since it was a laserdisc we could go frame by frame, and sure enough someone had added a single frame that said “PHYSICS IS FUN” on a black background. Which, like, I agreed, but didn’t need the subliminal programming to that effect.

5 Likes

Thanks for the angular momentum idea! I can think of something with that that might work.

I wanted to post some of the stupidest code I’ve ever written. I wanted to have a network of mirrors that you have to swivel to get a beam of light to travel around stonehenge. There were only 4 of them, and each can be set to the 8 normal horizontal directions.

But I wanted it to obey the reflection law, so I spent hours coding the angles of the incoming beam, the angle of the mirror, and the reflection, but I kept getting it wrong because I wasn’t clearly visualizing the difference between an incoming ray and an outgoing ray.

I knew I could just hand code all options for each light collector, but the issue is that I needed the system to ‘break the chain’ if a mirror in the middle got turned, I needed it to keep track of where the beam of light came in from and ended up. Also, if I did everything by hand, a bug might never show up, while if I had a system, it would show up.

The absolute biggest travesty in this is figuring out where the beam ended up by using trig instead of handcoding it, since that would have been 16 lines, but there’s some real sunk cost fallacy issues going on here. This code has about 15 ways it could be improved (like just adding 45 degrees to the angle each time its turned instead of the long list of things). So I’m posting it here as a cautionary tale (probably still doesn’t work!). It’s spaghetti code with pieces placed down wherever they fit, and about a dozen temporary variables.

Once I did it all I realized how simple it really was, but only because having the system showed me some mechanics I hadn’t anticipated (like the fact that light could be reflected directly back, or that once the initial choice of ‘cardinal’ or ‘ordinal’ directions is made at the north-collector [the light source], it can never be changed).

Summary
A light-collector is a kind of thing. [The printed name of a light-collector is "light collector".] Understand "light" or "collector" or "half" or "half-silvered" or "silver" or "silvered" or "half-silver" or "mirror" or "receptor" or "pivot" as the light-collector. The description of a light-collector is usually "FIX THIS LATER. It is pointing to the [pointure of the item described]. " 

Before writing a paragraph about a light-collector:
	all-lightcheck;

A light-collector is usually fixed in place. The description of a light-collector is usually "There is a light collector here, facing [pointure][if the item described is not listed in beam-list], but no light reaches it[otherwise if output-ang of the item described is -1]. Light beams from [the  resultant of reversified input-ang], but hits the backside of the collector[otherwise if output-ang of the item described is -2]. Light beams from [the resultant of reversified input-ang], but hits the side of the collector[otherwise if the resultant of reversified input-ang is the resultant of output-ang]. Light beams from [the resultant of reversified input-ang] and is reflected back in the same direction[otherwise]. Light beams from [the resultant of reversified input-ang] to [the resultant of output-ang]."

A light-collector has a direction called pointure. The pointure of a light-collector is usually northeast.

Instead of right-turning a light-collector:
	if the pointure of the noun is northeast:
		now the pointure of the noun is east;
	otherwise if the pointure of the noun is east:
		now the pointure of the noun is southeast;
	otherwise if the pointure of the noun is southeast:
		now the pointure of the noun is south;
	otherwise if the pointure of the noun is south:
		now the pointure of the noun is southwest;
	otherwise if the pointure of the noun is southwest:
		now the pointure of the noun is west;
	otherwise if the pointure of the noun is west:
		now the pointure of the noun is northwest;
	otherwise if the pointure of the noun is northwest:
		now the pointure of the noun is north;
	otherwise if the pointure of the noun is north:
		now the pointure of the noun is northeast;
	say "You turn [the noun] to the right. It now faces [pointure of the noun].";
	all-lightcheck;
 
Instead of left-turning a light-collector:
	if the pointure of the noun is northeast:
		now the pointure of the noun is north;
	otherwise if the pointure of the noun is north:
		now the pointure of the noun is northwest;
	otherwise if the pointure of the noun is southeast:
		now the pointure of the noun is east;
	otherwise if the pointure of the noun is east:
		now the pointure of the noun is northeast;
	otherwise if the pointure of the noun is southwest:
		now the pointure of the noun is south;
	otherwise if the pointure of the noun is south:
		now the pointure of the noun is southeast;
	otherwise if the pointure of the noun is northwest:
		now the pointure of the noun is west;
	otherwise if the pointure of the noun is west:
		now the pointure of the noun is southwest;
	say "You turn [the noun] to the left. It now faces [pointure of the noun].";
	all-lightcheck;

Instead of turning a light-collector:
	try right-turning the noun;

Directionsetting is an action applying to one thing and one visible thing. Understand "turn [a light-collector] to/-- [a direction]" or "set [a light-collector] to/-- [a direction]" or "push [a light-collector] to/-- [a direction]" as directionsetting.

Definition: a direction is cardinalish if it is north or it is south or it is east or it is west or it is northeast or it is northwest or it is southeast or it is southwest

Check directionsetting:
	unless the second noun is cardinalish:
		say "You can only turn [the noun] to a cardinal direction like north or east or an ordinal direction like northwest or southeast." instead;

Carry out directionsetting:
	now the pointure of the noun is the second noun;
	say "You turn [the noun] to face [the second noun].";
	all-lightcheck;
	
A light-collector has a number called the input-ang. A light-collector has a number called the output-ang.

To decide what number is the reflection of (firstnum - a number) by (secondnum - a number):
	let diffang be firstnum minus secondnum;
	let checkang be diffang;
	if checkang < 0:
		now checkang is checkang plus 360;
	if checkang is 90:
		decide on -2;
	otherwise if checkang is 270:
		decide on -2;
	otherwise if checkang < 90:
		decide on -1;
	otherwise if checkang > 270:
		decide on -1;
	let doubang be secondnum multiplied by 2;
	let nextang be doubang minus firstnum;
	let reflang be nextang plus 180;
	if reflang < 0:
		now reflang is reflang plus 360;
	if reflang > 360:
		now reflang is reflang minus 360;
	decide on reflang;

To decide what direction is the resultant of (current - number):
	if current is 0:
		decide on north;
	otherwise if current is 45:
		decide on northeast;
	otherwise if current is 90:
		decide on east;
	otherwise if current is 135:
		decide on southeast;
	otherwise if current is 180:
		decide on south;
	otherwise if current is 225:
		decide on southwest;
	otherwise if current is 270:
		decide on west;
	otherwise if current is 315:
		decide on northwest;
	otherwise:
		decide on up;
	
A light-collector has a number called x-coord. A light-collector has a number called y-coord. The x-coord of a light-collector is usually 0. The y-coord of a light-collector is usually 0.

The x-coord of north-collector is 1. The x-coord of south-collector is -1. The y-coord of east-collector is 1. The y-coord of west-collector is -1.

To say verbal-lightcheck:
	all-lightcheck;

To all-lightcheck:
	let K be the number of entries in beam-list;
	repeat with current running from 1 to K:
		unless the number of entries in beam-list < current:
			lightcheck current;
	let templight be a random light-collector in the location;
	if templight is not nothing:
		if templight is not listed in beam-list:
			say "You can see [a templight] here. There is little light in this location, although there is enough to see by.";
		
To decide what number is reversified (current - a number):
	if current < 180:
		decide on current plus 180;
	otherwise:
		decide on current minus 180;
		

WHen play begins:
	say "The reflection of 10 by 0 is [the reflection of 10 by 0]";
	say "The reflection of 350 by 0 is [the reflection of 350 by 0]";
	say "The reflection of 10 by 90 is [the reflection of 10 by 90]";
	say "The reflection of 350 by 90 is [the reflection of 350 by 90]";

A light-collector can be doubled or not doubled. A light-collector is usually not doubled.

To lightcheck (currentnum - number):
	let current be entry currentnum in beam-list;
	let templist be beam-list;
	truncate templist to (currentnum - 1) entries;
	if current is listed in templist:
		if current is in the location:
			let current2 be entry (currentnum - 1) in beam-list;
			say "[line break]Another beam of light enters from [the resultant of reversified output-ang of current2]."; 
	otherwise if current is north-collector:
		if the north-collector is in the location:
			say "The light from the stars above is reflected off to [pointure of north-collector].";	 
		let temptarget be the light-target of current by bearing of north-collector;
		if temptarget is north-collector:
			truncate beam-list to 1 entry;
		otherwise:
			now the output-ang of current is bearing of north-collector;
			now the input-ang of temptarget is bearing of north-collector;
			truncate beam-list to 1 entry;
			add temptarget to beam-list;
	otherwise:
		let tempang be input-ang of current;
		let tempbear be the bearing of current;
		let resultantang be the reflection of tempang by tempbear;
		let temptarget be the light-target of current by resultantang;
		truncate beam-list to the first currentnum entries;
		now the output-ang of current is resultantang;
		if temptarget is current:
			do nothing;
		otherwise:
			now the input-ang of temptarget is resultantang;
			add temptarget to beam-list;
		if current is in the location:
			let tempinput be the input-ang of current;
			let backang be reversified tempinput;
			let tempoutput be the output-ang of current;
			if tempoutput is -1:
				say "The light comes in from [the resultant of backang] but hits the backside of [the current], which is facing [pointure of current].";
			otherwise if tempoutput is -2:
				say "The light comes in from [the resultant of backang] but hits the edge of the [the current], which is facing [pointure of current].";
			otherwise if backang is tempoutput:
				say "The light comes in from [the resultant of backang] and is reflected right back by [the current], which is facing [pointure of current].";
			otherwise:
				say "The light comes in from [the resultant of backang] and bounces off [the current] (which is facing [pointure of current]) to [the resultant of tempoutput].";

To decide what light-collector is the light-target of (current - a light-collector) by (resultantang - a number):
	if resultantang < 0:
		decide on current;
	if the resultantang is 90:
		if current is west-collector:
			decide on east-collector;
		otherwise:
			decide on current;
	otherwise if the resultantang is 270:
		if current is east-collector:
			decide on west-collector;
		otherwise:
			decide on current;
	otherwise:
		repeat with templight running through light-collectors:
			if templight is current:
				next;
			let xdiff be x-coord of current minus x-coord of templight;
			let ydiff be y-coord of current minus y-coord of templight;
			if xdiff is 0:
				next;
			let tempfrac be ydiff divided by xdiff;
			let tempbear be resultantang;
			let tempdeg be tempbear degrees;
			let temptan be tangent of tempdeg;
			let tempsin be sine of tempdeg;
			let tempy be ydiff multiplied by tempsin;
			let tempcos be cosine of tempdeg;
			let tempx be xdiff multiplied by tempcos;
			let tempsum be tempx plus tempy;
			let tempdiff be temptan - tempfrac;
			if tempdiff > 0:
				if tempdiff < 0.0001:
					now tempdiff is 0;
			if tempdiff < 0:
				if tempdiff > -0.0001:
					now tempdiff is 0;
			if tempdiff is 0:
				if tempsum < 0:
					decide on templight;
	decide on current;

The beam-list is a list of light-collectors that varies. The beam-list is {north-collector}.

To decide what number is the bearing of (current - a light-collector):
	if the pointure of current is north:
		decide on 0;
	otherwise if the pointure of current is northeast:
		decide on 45;
	otherwise if the pointure of current is east:
		decide on 90;
	otherwise if the pointure of current is southeast:
		decide on 135;
	otherwise if the pointure of current is south:
		decide on 180;
	otherwise if the pointure of current is southwest:
		decide on 225;
	otherwise if the pointure of current is west:
		decide on 270;
	otherwise if the pointure of current is northwest:
		decide on 315;

Chapter 1 - Stonehenge room

Stonehenge-region is a region. Stonehenge-region is in monument-region.

The stonehenge-east is a room in stonehenge-region. The printed name of the stonehenge-east is "East of Stonehenge".  The description of the stonehenge-east is "[first time]FIX THIS LATER There is lower gravity here. [only]There's a box labelled LOST AND FOUND here."

The east-collector is a light-collector in stonehenge-east.

Section 1 - [taken out for this post]

Section 2 - Center stonehenge

The stonehenge-center is a room in stonehenge-region. The stonehenge-center is west from stonehenge-east. The printed name of the stonehenge-center is "Stonehenge". The description of stonehenge-center is "You can go [boldnorth], [boldeast], [boldsouth] or [boldwest]."

Section 3 - North stonehenge

The stonehenge-north is a room in stonehenge-region. The stonehenge-north is north from stonehenge-center. The stonehenge-north is northwest from stonehenge-east. The printed name of the stonehenge-north is "North of Stonehenge". "The starlight is especially bright on this side. Many of the stones are missing, only their empty sockets witnessing to what once was."

The north-collector is a light-collector in stonehenge-north. The description of the north-collector is "This light collector is tilted up at a 45 degree angle, receiving light from the stars. It's currently facing [pointure of north-collector]." The initial appearance of the north-collector is "[one of]A[or]The[stopping] light collector here is tilted partially up to the sky, absorbing some light from the stars and reflecting the rest in a faint beam to the [pointure of north-collector]."	

Section 4 - West stonehenge

The stonehenge-west is a room in stonehenge-region. The stonehenge-west is west from stonehenge-center. The stonehenge-west is southwest from stonehenge-north. The printed name of the stonehenge-west is "West of Stonehenge".

The west-collector is a light-collector in stonehenge-west.

Section 4 - South stonehenge

The stonehenge-south is a room in stonehenge-region. The stonehenge-south is south from stonehenge-center. The stonehenge-south is southeast from stonehenge-west. THe stonehenge-south is southwest from stonehenge-east. The printed name of the stonehenge-south is "South of Stonehenge". The description of stonehenge-south is "FIX THIS LATER There's a lintel here."

The south-collector is a light-collector in stonehenge-south.

Section 5 - Beam crossing

The light-beam is an intangible thing. The printed name of the light-beam is "beam of light". Understand "beam" or "beam of" or "light" as the light-beam. The initial appearance of the light-beam is "You can see a beam of light shining [beamdesc]."

The description of light-beam is "While you can't see the source, you can see a beam of light shining [beamdesc]."


beamdesc is some text that varies.

Opposition relates one light-collector to another. The verb to face means the opposition relation.

The south-collector faces the north-collector. The east-collector faces the west-collector.

Every turn when the player is in stonehenge-region:
	now the light-beam is nowhere;
	let lastlight be north-collector;
	repeat with current running through beam-list:
		if current faces lastlight:
			now light-beam is in stonehenge-center;
			let tempang be input-ang of current;
			now beamdesc is "from [the resultant of reversified tempang] to [the resultant of tempang]";
			break;
		now lastlight is current;

Edit: Also, I know ‘pointure’ doesn’t mean ‘where it’s pointing’, it means ‘shoe size’, but I liked the way it sounded. And all the temp variables with ‘ang’ in them stand for ‘angle’.

Nothing else in this game has been this annoying to code, and it’s not even going to be apparent to the player. It honestly might be better to just strip the whole thing out, but it kind of works now.

This really made me realize why people never implement rope, because a long rope would need all the stuff I was just talking about (like cutting it in the middle messing up other stuff) as well as a host of other things.

5 Likes

Had a Taj Mahal area, because I thought it was just a tomb, but apparently part of it’s a mosque? I’ve been trying to avoid religious buildings due to respect (I had Chichen Itza and one of the large statues of Buddha before but got rid of them for the same reason). So I’m changing it to Tower of London; I can’t imagine many people getting mad about looting the Tower.

4 Likes

I mean I can think of a few.

(Seriously, this is a good practice! There is a small chapel in the Tower, I believe, but it’s probably easy enough to omit it and I doubt anyone would notice).

5 Likes