HTML Anyone know how to turn off/on switches in an HTML game?

Aug 16, 2020
16
14
I know how to change variables, but I want to change the state of a switch in an HTML game. By a switch, I mean something that activates or deactivates a mode in a game. Lets just say, for a quirky example, whether the protagonist has completed a quest or not. Or if there is a special mode enabled, like a supporter mode ;).
EDIT: I thought I put this in off-topic, but I guess I didn't. My brain rot must be acting up. But as long as it doesn't get deleted, I'll keep it here I guess

EDIT 2: Alright, my question has been answered. I'll leave this up for other and myself to reference it later
 
Last edited:

Jofur

Member
May 22, 2018
251
269
I'm not hugely familiar with HTML games, but can't you use a boolean, I.E true/false variable?
Something like "specialModeEnabled = false".
 

arnii

Massive Member
Game Developer
Feb 23, 2020
140
362
I know how to change variables, but I want to change the state of a switch in an HTML game. By a switch, I mean something that activates or deactivates a mode in a game. Lets just say, for a quirky example, whether the protagonist has completed a quest or not. Or if there is a special mode enabled, like a supporter mode ;).
It's kind of an open-ended question, with HTML not being a constrained game engine with any set rules about how you do and how you don't do things. What you typically want to do with your JS code is to have some sort of 'state' object which records the progress that the player has made and what settings they have configured. You then refer to this state object in your game using conditionals (e.g. if(stateObject.SpecialQuestComplete === true) { //do something }else{ //do something else }.
 
Sep 4, 2020
91
47
All computer programming is "state" programming. In fact, a computer program can be seen as the "initial state" of memory -- it's loaded, you let the CPU loose on it, and what follows are just subsequent state changes defined by the current state of memory and the clock clicking forward by one.

OK, that's getting philosophical.

But on a practical level, you could create a set of "state" variables. There's nothing special about them except to you -- reserve them to define the state of the game and nothing else. The problem becomes the proliferation of variables.

If you really want to get professional with it, hide the variables behind method (aka function) calls:

function advanceQuestState(questName)
function setQuestChoice(questName, choice)
function currentQuestState(questName)

That's just a suggestion. It might not work without some extra bits. But it's to get you thinking.

Inside the code, there are different chunks for each questName. Each chunk knows how the named quest proceeds, or is affected by a choice. The code can also handle housekeeping duties and side-effects (for instance, when the "Get knighted" quest gets to 3rd stage the MC's name is now "Sir MC", which is done by adjusting the name variable -- the outside code never has to check whether it's time to use "Sir MC" since it just starts happening when it needs to). If you accidently mistype the questName, the method can crap out with a big error message, which can help you with your debugging.

Internal to those methods, you can use a bunch of variables, or an object, or whatever -- you can even change your mind later and the rest of your code won't care, because they rely on those method calls and not on how the method calls actually work.
 

HiEv

Member
Sep 1, 2017
384
778
I know how to change variables, but I want to change the state of a switch in an HTML game. By a switch, I mean something that activates or deactivates a mode in a game. Lets just say, for a quirky example, whether the protagonist has completed a quest or not. Or if there is a special mode enabled, like a supporter mode ;).
Besides what everyone else has said, which boils down to "just set a variable and then check that variable's value as needed," I'll show you a trick to do it which takes up less memory. This is handy for any games with Twine-like systems, where each step of the game's history is recorded during a playthrough, thus minimizing the size of that history data is helpful.

So, let's take your quest tracking example. Let's say that there are 20 quests in your game. Rather than setting 20 different variables, using an array with 20 elements, or even creating an object with 20 properties, you can track completion of all of those quests using a single variable that just holds one integer value.

In JavaScript you can do " " on the first 32 bits of integers. This means that you can treat a single integer as though it contains up to 32 on/off switches, with each switch represented by a single bit (a 0 or 1) in the integer.

If you initialize a variable by setting it to the integer 0, then it's like setting all of the switches to "off" in that integer variable. You can then turn on a "switch" in that integer like this:
JavaScript:
quests = quests | Math.pow(2, questNumber);
In the above code, quests is assumed to already be initialized and questNumber will need to be an integer from 0 to 31, representing which quest is being marked as completed. See the and the documentation for details on those.

Also, if you want to turn off a bit in an integer, you can do this:
JavaScript:
quests = quests & ~Math.pow(2, questNumber);
See the and documentation for details on those.

You can then check to see if a quest was completed like this:
JavaScript:
if (quests & Math.pow(2, questNumber)) {
    /* Quest was completed code goes here. */
} else {
    /* Incomplete quest code goes here. */
}
Also, keep in mind that, if you're just using the first 20 bits for quests, then there are still 12 other bits remaining on that integer which you could use to track other true/false conditions, such as for enabling your super secret supporter special mode.

Those three pieces of code should give you all you need in order to use the bits in an integer as switches for your game.

If you want to see a somewhat more elaborate version of that with further explanations, you could take a look at the " " section of my .

Hope that helps! :)
 
Last edited:
Sep 4, 2020
91
47
In JavaScript you can do " " on the first 32 bits of integers. This means that you can treat a single integer as though it contains up to 32 on/off switches, with each switch represented by a single bit (a 0 or 1) in the integer.
Bitwise flags? I mean, yeah, I've done that. When I was programming embedded software for aerospace, where literally every byte counted because the board had all of 8K on it, and that was for everything -- firmware, BIOS, working memory, stack, heap.

On a modern computer laptop, where 8M is the starting point, there really is no need for that level of space-saving sophistication. I did consider mentioning it, but then I thought, "Nah, who would do that these days unless programming right on the metal?"

Huh, I guess my answer "No one would!" was wrong.

But kudos to you for bringing it up and challenging these people to dial up their programming up to 11. My one caveat would be to hide the bitwise coding behind method calls. So something like IsQuestDone(questIndex) would return true or false for anyone asking, and the code making the call would never be exposed to the bitwise stuff happening inside. Heck, I even did that in that embedded software because, even though it cost a bit of memory to do it, it made the code walkthroughs so much easier. (And with generous use of the inline pragma, it didn't even really cost that much in code size.)

[As a fun aside, I wrote code that actually did the bitwise stuff in pure assembly to make sure it was small and it was fast, since it was being called a so often -- lots of bitwise left and right shifts. The rest of the code was done in Ada.]
 

HiEv

Member
Sep 1, 2017
384
778
On a modern computer laptop, where 8M is the starting point, there really is no need for that level of space-saving sophistication. I did consider mentioning it, but then I thought, "Nah, who would do that these days unless programming right on the metal?"

Huh, I guess my answer "No one would!" was wrong.
Well, you have to keep in mind that the on non-Firefox browsers shares the same 10 MB (or 5 MB on mobile) across all local files (i.e. all HTML files on your computer). So, even if your game's saves aren't taking up much space in localStorage, other games' data could be. (Firefox does a better job of this, where each local file gets its own 10 MB chunk of localStorage based on filename and file path.)

That's why I wrote my HTML page, which you can download and use to help manage localStorage for HTML games that you've set up on your computer. Also, if you need to work with localStorage or saving and loading files, then you might want to import it into the Twine editor and take a look at the code it uses.

Additionally, keep in mind that, if you have SugarCube tracking up to 100 entries in the game's history (you can change this by adjusting the ), then that means that you could have up to 100 versions of some data in the game history. Even if it's something that only takes up about 100 bytes of data, when you multiply that by 100 entries in the game's history, it's now about 10,000 bytes, or just shy of 10 kB for that one tiny bit of data. Technically it probably takes up less space than that in localStorage, because the story variable's name is also stored (which adds more data), SugarCube tracks only the changes in the history (which reduces the size of the data), and then that history data (which reduces the size of the data even further), but that's still more data to compress, thus more slowdown for saves, loads, and passage transitions.

All of that is why it's a good idea to minimize history usage however you can.

My one caveat would be to hide the bitwise coding behind method calls. So something like IsQuestDone(questIndex) would return true or false for anyone asking, and the code making the call would never be exposed to the bitwise stuff happening inside.
Yeah, if you take a look at the " " I linked to, it pretty much does that, though in a more generic form.

As a fun aside, I wrote code that actually did the bitwise stuff in pure assembly to make sure it was small and it was fast, since it was being called a so often -- lots of bitwise left and right shifts.
I did that as well. I studied in college (only person in my class to finish the final exam before time ran out too, despite renaming most of the variables and then the teacher demanding that I rename them back) and I've since used to optimize code on Windows several times.

Fun stuff! :cool:
 
Last edited:
  • Like
Reactions: stevejackhammer
Sep 4, 2020
91
47
...

All of that is why it's a good idea to minimize history usage however you can.



I did that as well. I studied in college (only person in my class to finish the final exam before time ran out too, despite renaming most of the variables and then the teacher demanding that I rename them back) and I've since used to optimize code on Windows several times.

Fun stuff! :cool:
Good point about the local storage. But people ought to realize that the bitwise approach is really only good for Booleans. This happened or it did not happen. State such as "hit points" or "MC's name" still require many bytes of data.

And we should fill the forum up swapping war stories! Kids today with their i9 processors and GPUs. We programmed on 8086s. We were excited when a new version of DOS was released. X11 was the only window scheme around, not that we CLI types had any complaints with VMS. Muscle memory was reserved for Emacs keyboard macros. And who needed dialog boxes when the minibuffer told you all you needed to know? I could go on, but there are kids outside, and I need to yell at them to get the hell off my lawn!
 

HiEv

Member
Sep 1, 2017
384
778
Good point about the local storage. But people ought to realize that the bitwise approach is really only good for Booleans. This happened or it did not happen. State such as "hit points" or "MC's name" still require many bytes of data.
True-ish. However, if you need to keep track of a bunch of things, each of which could have one of 3 or 4 values, then you could do that with 2 bits per item, so up to 16 items per integer. 3 bits works for up to 8 values, 4 bits up to 16 values, etc... So you don't have to only use them as Booleans, you can just use them as a way to compact your data.

You probably get that already, but your wording indicates otherwise, so I just wanted to make that point clear.
 
Sep 4, 2020
91
47
True-ish. However, if you need to keep track of a bunch of things, each of which could have one of 3 or 4 values, then you could do that with 2 bits per item, so up to 16 items per integer. 3 bits works for up to 8 values, 4 bits up to 16 values, etc... So you don't have to only use them as Booleans, you can just use them as a way to compact your data.

You probably get that already, but your wording indicates otherwise, so I just wanted to make that point clear.
Yeah, if my state variable wasn't a simple on-off flag but something with 6 states, I'd need 3 bits. You get that. I get that. But I think it's pretty advanced stuff for most people (even for most programmers I know, frankly). And even I would pause to consider if that level of bit-packing sophistication was really justified, even though I could code it up easily enough.

If I needed 32-bits to store all that state, I'd be nervous. Unless the game was actually 100% done, I'd be worried that another state variable would crop up needing one more more bits and now I'm in a bind, having run out of bits.

[For neophyte programmers, optimization is usually late because you don't know until you're done** whether you even have performance issues, and if you do, is it speed or size. And where? Images too big, bloated state variables, coding inefficiencies -- each potential problem has a very different solution.

** "Done" doesn't always mean final version. It can be an intermediate release that has 40% of the game implemented, for example, but enough so that problems are starting to manifest.]
 

HiEv

Member
Sep 1, 2017
384
778
Yeah, if my state variable wasn't a simple on-off flag but something with 6 states, I'd need 3 bits. You get that. I get that. But I think it's pretty advanced stuff for most people (even for most programmers I know, frankly).
You know, I was going to feel a tiny bit offended that you didn't actually check out my , which already handles doing that using the getVal()/setVal() functions it provides, but then I discovered that the forum had been breaking my links to it. :cautious: Goddamnit.

Anyways, links are fixed now, so you can see that I already implemented that for beginners. (Note to self: Don't use Bitly links here anymore. :p )

If I needed 32-bits to store all that state, I'd be nervous. Unless the game was actually 100% done, I'd be worried that another state variable would crop up needing one more more bits and now I'm in a bind, having run out of bits.
You just create another integer if you need more bits. It's not like you're going to run out of those. :p

Anyways, I'm sure we've bored everyone to tears here about this subject. So, unless anyone has any questions on the code, I'll end my comments on this here.
 

Sagisu

Newbie
Nov 12, 2017
29
24
Q: how can I do switch in HTML?
A: let's talk about bitwise operations and assembly code...

Wow guys.. simpliest answer is: you cannot.. use JS/TS for it =p
 
  • Haha
Reactions: stevejackhammer