The Dink Network

Reply to Some self-indulgence

If you don't have an account, just leave the password field blank.
Username:
Password:
Subject:
Antispam: Enter Dink Smallwood's last name (surname) below.
Formatting: :) :( ;( :P ;) :D >( : :s :O evil cat blood
Bold font Italic font hyperlink Code tags
Message:
 
 
June 16th 2012, 03:42 AM
fairy.gif
Someone
Peasant He/Him Australia
 
I've always felt MouseDink has been a little underappreciated in two ways. First, I think that many people didn't figure out how to properly play MouseDink and were consequently overly negative about the gameplay. And second, the [almost] lack of use of any of the elements from MouseDink in any newly developed DMOD, even though I tried to describe many of them in my advanced DinkC tutorial. Since creating MouseDink I've wanted to create a video where I'd talk/walk the viewer through MouseDink and show how to play it, but I've never got around to it because of the difficulty and effort it would take to record my own video. Since I'll probably never get around to it, I'm just going to write it down here as best I can remember.

First, the gameplay. I was quite explicit in the readme that MouseDink is a demonstration of a set of scripts and the gameplay was not optimised. However, I did actually give some thought and spent some time tweaking the gameplay. Unfortunately, without the video it may be hard to see that MouseDink is quite playable once you figure it out.

The gameplay was designed to still feel like "Dink" while being mouse-based. The gameplay of Dink is absurdly simple: you hit, back off, hit, back off, etc. In MouseDink you do the exact same thing. Admittedly, it's a bit weird with touch-based enemies [e.g., pillbugs] because the challenge is to stop Dink from running into the pillbugs, but it feels natural with attacking enemies [e.g., the bonca]. You click the bonca, Dink runs up and hits it, and you have to click away at just the right time then repeat. It's Dinky, and it's mouse-based, and in my opinion it feels a little bit more natural with attacking based enemies than the original Dink. Once you give it a bit of practice you should be able to kill all the enemies without much trouble. Yes I made Dink a bit quick and the "window" where you have to click back a bit small, but I wanted to make it challenging and both these things can be changed with a single number anyway. I think people may be criticising the gameplay before they master it. Also you need to click in the hitbox of the enemy.

I really like bows [at least in the Elder Scrolls series and some other games] so I wanted to make a worthy Dink bow mechanic. All ranged weapons in Dink are pretty much broken because either they work way too well or they take too long to kill and patience wears out. In sum, if they do work, there's no skill to it and no risk of you getting hurt. There's no strategy to it. So to combat this, [if my memory serves me correctly], the delay for the pullback is quite slow relative to how fast the bonca moves. You have to aim and fire quickly before retreating for the next shot. This makes the bow both useful but a little tricky and requires a little bit of skill - something not present in the original Dink.

Of course the gameplay can be altered. MouseDink can be altered to make Dink kill and dodge enemies by just clicking on them. Diablo gameplay can be completely replicated. Either of these changes are relatively trivial to the task of programming the base framework for MouseDink so I don't think the criticism that a few people have had that I didn't optimise the gameplay according to their particular preference is really fair..

MouseDink clearly also spawns ideals of using the keyboard and mouse together to control Dink. I've probably talked about this before. My desire for bow-based combat has attracted me to think about this as well, because I think it would be superior for bows. Using the keyboard to control Dink and the mouse to aim is possible and I've scripted it. It's not hard and although I've lost the scripts I could write it again. I've also written scripts such that a second player can control a second Dink, which is similar to the issue of having mouse+keyboard together.

There is a problem though, and that is being in mouse-mode disables all keyboard input except for wait_for_button. That includes disabling the key-X.c inputs. Wait_for_button only responds to a few keys [arrow keys, ctrl, shift, esc...]. So no WASD control when the mouse works. The other bother is that there is no way to know if the player is holding down a button with wait_for_button. With the key-X.c, I came up with a [lagged] solution to that, because key-X.c is run every 50/100ms or something when the button is held down. However no such solution works for wait_for_button. So, you can use the keyboard but you would have to tap the keys for the player to start moving or stop.

It's not that bad though and I was working on an arcade-like game [one screen deathmatch sort of thing] where you control Matridge and cast spells with the mouse. I didn't finish it though. I was also flirting with selecting spells based on making patterns with the mouse cursor [ala black and white] but I wasn't confident it would work perfectly. Anyway, because I'm more motivated by the challenge of scripting than a polished product, I didn't finish it.

Second, people not using elements from MouseDink. OK, I will really be blowing my own horn here, because it will require a summary of scripting inventions introduced in MouseDink. The scripting in MouseDink has obviously been more appreciated than the gameplay but still many elements that could be borrowed for new DMODs haven't been. Perhaps that is more of a reflection of the dearth of DMODs in the last few years . Nevertheless, I'm going to indulge myself here. I'd also like to offer my apologies if any of these inventions were used prior to MouseDink and I am unaware of them.

Scripting elements:
* Use of juggle variables. Juggle variables are variables used for multiple purposes. I described them in my tutorial. You need to have some idea of how waits work to use them reliably. Through using them, MouseDink uses at most 16 variables at any time, despite its unholy complexity. This makes the code hard to read yes, but it's not without purpose because of the variable limit.

* More systematic use of "supervars". Supervars are variables that hold multiple "pieces" of information in one variable. They were well described by other authors prior to MouseDink but somewhat simplistically, tending to limit variables to be values 0-9 rather than the range needed for that variable. My contribution was scripts that read/write to supervars, allowing you to choose the range so you can store variables that range for example between 0-20 or many variables with small ranges.

I believe in my tutorial I've stated that the original Dink could be rewritten to use 4-6 or so variables at max on top of the engine required variables, using juggle variables and "supervars". I think this is pretty significant because of how common it was [and still is] for people to claim they can't do something because of the variable limit. In MouseDink the data required to store the inventory is tremendous because the order of the inventory is saved. There is no way you can dedicate eg 40 variables for the inventory; it is way too much. Instead the inventory is stored in 4 [I think] variables.

* Basically rewriting all behaviors associated with brain 1 and sprite 1 into DinkC [e.g., moving, getting hit, triggering screen changes, hitting, dying]. This is the essence of what MouseDink is and I wish people would judge it on that. Anyway, replacing the important brain 1 code internally in Dink.exe with DinkC code means much more power to the developer in tweaking things.

* Dividing with integers. 1 problem which limited some developments is that you can't easily store the value of a decimal in Dink. So my solution was to inflate values by some number so that you can effectively. I think I described this in my tutorial too. So instead of trying 7/2 = 3 we can do 7000/2000 = 3500 and get that bit of information [the .5] that would be lost otherwise. Of course it's better to multiply our variables by a number such that the largest possible value we would store in the variable becomes the largest possible value that can be stored in the variable to maximise the amount of information that can be saved. [e.g. multiplying by 1000 will help us save more information than 100, but it might cause a value to overflow, so we pick the largest constant that won't cause overflow.]

The dividing with integers thing allows Dink to shoot his bow in any direction. Dividing like this may seem kind of obvious in hindsight, but it's not. For ages one of the major "problems" people were interested in were enemy-shoot scripts. There are a few that are uploaded here. They can only shoot in 4-8 directions, but in MouseDink there is an example of an enemy-shoot script that shoot in any direction [almost infinite number of directions!]. There was actually another difficulty to do this. For example, shooting an arrow 5 points right and one down is tricky. You can't just do sp_mx[x,5] because the arrow will jump across 5 pixels at time, and you can't do something like sp_mx[x,2.5], sp_my[x,-.5] because Dink only allows integers. So instead you have to do something tricky like move the arrow right by 2 every x milliseconds and move the arrow down by 2 every 5*x milliseconds. The brain smooths over motion so it's imperceivable. To write that down to deal with every possible ratio of mx to my ends with some hard to read code, but that's because it's complex, not because I was trying to make things look more technical than they are.

* Heavy use of the missile brain. Admittedly this isn't original as I've later found out that other DMODs have seen how wonderful the missile brain is [at least Dinkanoid uses it similarly]. Basically exploiting that the Dink engine enables a lot of functionality for the missile brain [animation, movement and touch] but otherwise leaves it alone [unlike the enemy brains]. From memory, in MouseDink the enemies as well as Dink and basically everything else except for the cursor and an invisible catch-all button are all missile brains.

* Use of infinite loops. Basically the use of a loop with minimal wait [eg wait 0 or 1] that runs constantly and checks for certain conditions. Very powerful
and MouseDink wouldn't be possible without it.

* Having a script constantly waiting_for_button at all time. This is how MouseDink receives keyboard strokes while the mouse is active. Also, I think I put a large invisible sprite under everything to catch mouse clicks.

Last and least

* Smooth pushable objects [check out the barrel!] Admittedly it's not quite as nice in normal Dink as it is in MouseDink, but it works there as well. For someone [Christiaan?] I modified it so momentum can travel from one barrel to another if one gets hit into another, and also so the pushing animation comes up.

There might be one or two I missed as it has been a long time since I wrote MouseDink. The health of enemies is 'saved' if you exit/re-enter a screen, for example, by using editor_seq to store the health. I'll also take this time to confess that Dink getting hurt and dying when he tries to enter a screen that doesn't exist... I don't know why that happens but it's awesome and looks intentional so I left it. The poison thing where poisoned arrows have the poisoned effect wasn't originally intentional either but it too looks awesome so I put it in properly.

So these are two things I wanted to do for a long time. Describe how to actually play MouseDink [although I wanted to do so in a video..] and describe in some more detail script innovations in MouseDink to encourage people to use them in their own scripting. I'll admit a little vanity gave me the final motivation to finally write something like this up. I think the least of my innnovations, the smooth pushable barrel, deserves more than a 6. Or finally coming up with a decent enemy shoot script after years of suboptimal ones, even by godly scripters like Paul/manauser? Let alone MouseDink that was twenty times more complex than either of those? And MouseDink isn't needlessly difficult to decipher, it's hard to decipher because it is really complicated. Picking the largest possible value to prevent overflow when "dividing," dealing with projectiles that can move with weird x/y ratios, trying to respond to keyboard input when dink.exe has disabled all but wait_for_button, trying to immediately respond to events when dink.exe doesn't inform you when they occur, having a fake Dink with a fake brain 1, optimised supervars and especially juggle variables make the code needfully difficult to decipher. Also, the thought that someone can write their own version of MouseDink without using any of my scripting technologies, using MouseDink as just a "handy reference" is totally naive to how MouseDink works. The idea of someone optimising the gameplay of MouseDink and calling it their own version while mine was merely a "reference" is offensive to me. Gameplay optimisations are the icing on the cake and 95%+ of the code would be unchanged. MouseDink with CTRL as attack is still MouseDink.

I don't think there was any malice in the review and in my opinion it probably reflects common misunderstanding of MouseDink because I've neglected polishing it or previously defending it.. so please forgive my self-indulgence to do so here, in hopes people can see MouseDink in fair light I hesitated to mention the review, but I figure it's kind of obvious it was the last bit of motivation it took for me to write this. Besides, I think I'm justified to express my offense to the idea of someone using MouseDink as a "handy reference" to "do it yourself." The solutions I came up with are too fundamental to just tackle the problems differently and yes it's vain but they are mine. I already had my Fairy Goodness DMOD bastar dised without my permission.

I'd still love to see a MouseDink DMOD, and hopefully this post reminds potential developers of the possibility

EDIT: dang, longest post ever?