Is this possible in BYOND without using Icon procs? Animate blurs the heck out of everything.

Yes and no.

There's a trick to what I'm doing. I determine the maximum scale I'll need for the icon and then upscale the original icon during initialization. BYOND automatically prevents the re-creation of identical icons if you've already got it in the cache. It's incredibly good at it too. Way better than any softcode system you are going to cook up to prevent it.

Once I've got the maximum required scale (ceil), I simply downscale to the current scale rather than upscaling.

For most visual effects, anything over 4x original scale is unnecessary.

Both of the gifs you linked are recorded in BYOND using animate(). One of the objects uses animate() upscaling, one uses animate() downscaling. This is recorded live with both objects in the frame at the same time.

identity matrix is simple for downscaling:

matrix(SCALE/MAX_SCALE,0,(WIDTH*SCALE-WIDTH*MAX_SCALE)/2,0,SCALE/MAX_SCALE,(HEIGHT*SCALE-HEIGHT*MAX_SCALE)/2)


Which can be expressed as:
var/sfac = SCALE/MAX_SCALE
var/ofac = SCALE-MAX_SCALE
var/HW = WIDTH/2, var/HH = HEIGHT/2
matrix(sfac,0,HW*ofac,0,sfac,HH*ofac)


Or the functional way:

var/matrix/m = matrix()
var/sfac = SCALE/MAX_SCALE
m.Scale(sfac,sfac)
var/HW = WIDTH/2
var/HH = HEIGHT/2
var/ofac = SCALE-MAX_SCALE
m.Translate(HW*ofac,HH*ofac)

Whoo, first large gif!

Weapons now have a sighted range that will shift the camera in the player's direction when aiming/using them. This gives scoped weapons a ranged advantage and short ranged weapons get the advantage of seeing enemies coming up behind them sooner. I'm still playing with this and I'm quite fond of the effect. Credit to Yutty Putty for suggesting and providing the sample.

In response to Kumorii
Can you trigger scoped view whenever you want :o? or is it automatic?
In response to Ghost of ET



Feed:
- Hellbats no longer blur to hell and back when flying.

Ghost of ET wrote:
Can you trigger scoped view whenever you want :o? or is it automatic?

No, however I could see about making it manually toggled with Q, if popular opinion sways that way!
In response to Ter13
So you scale them up ahead of time with the Icon procs, then downscale/rotate with animate() and it isn't all blurry?
So you scale them up ahead of time with the Icon procs, then downscale/rotate with animate() and it isn't all blurry?

Exactly. Downsampling comes out looking more pixelated and with less blurring. Some is still present, but it's overall a much better looking effect.
It's due to the fact that it's easier to guess what needs to be removed, than guess what needs to be added.

Upscaling is guessing at what needs to be added, Downscaling guessing what needs to be removed.
Feed:
- The location of the last three enemies in each wave will now be displayed on screen with arrows. Thanks Kaio!

Upscaling is guessing at what needs to be added, Downscaling guessing what needs to be removed.

Exactly. Similar concept to digitally remastering a video. Dropping resolution is no problem. Increasing resolution creates all kinds of visual artifacts.
"BYOND is holding me back" - Koz 2016 (Approx 1 week before returning to BYOND)
In response to Rushnut
Rushnut wrote:
"BYOND is holding me back" - Koz 2016 (Approx 1 week before returning to BYOND)

Shhhh... No. Stahp.
Go Madrid....
2-1 Madrid :D
Squaring an unsigned double!
Square()
// Returns the square of the src object, that is src**2. There are a few slight simplifications
// that can be made in this method that are not possible in the multiply method, due to different
// assumptions. In most situations, the computational difference between these two should be quite
// slim and largely irrelevant, but if you're doing a lot of computations (especially exponentiations)
// at once, they should be helpful.

var
// The final result.
pif_LongInt/UnsignedDouble/Square = new(0)

// Bytes of src.

src0 = src.block_1 & 0x00FF
src1 = (src.block_1 & 0xFF00) >> 8
src2 = src.block_2 & 0x00FF
src3 = (src.block_2 & 0xFF00) >> 8

// Bytes of the final result's blocks. As in the multiply method, the first byte of each
// of these is the actual value, while the second byte is a buffer until that data is
// pushed (i.e., added) to the next block.

byte_1 = 0
byte_2 = 0
byte_3 = 0
byte_4 = 0

// Buffer to temporarily store multiplications.

buffer

/*
*
* Performing the computation.
*

The idea behind the computation basically follows as above. That is, we let

A = r**3 a_3 + r**2 a_2 + r a_1 + a_0

where 0x00 <= a_n <= 0xFF. Then,

A*A = r**6 (a_3*a_3) + r**5 (2 a_2*a_3) + r**4 (2 a_1*a_3 + a_2*a_2) + r**3 (2 a_0*a_3 +
2 a_1*a_2) + r**2 (2 a_0*a_2 + a_1*a_1) + r (2 a_0*a_1) + a_0*a_0.

and we can disregard the terms with coefficients of r**6, r**5, or r**4. Now, when performing
these computations we have several fewer multiplications, as well as some multiplications by
2. The multiplications by two can simply be treated as a bitshift by one to the left.

Upper bounds at each step (i.e., after summing the terms of each given coefficient) are exactly
the same as in multiplication. This is because when doing multiplication, we tacitly assume (for
the purposes of upper bounds) that we're computing 0xFFFFFFFF*0xFFFFFFFF = (0xFFFFFFFF)**2.

*/


// Terms with coefficient r**0 == 1.

byte_1 = src0*src0
byte_2 = (byte_1 & 0xFF00) >> 8
FLUSH(byte_1)

// Terms with coefficient r**1 == r.

buffer = src0*src1 // *2

byte_2 += (buffer & 0x00FF) << 1 // By bitshifting by one, we multiply by two.
byte_3 = ((byte_2 & 0xFF00) >> 8) + ((buffer & 0xFF00) >> 7) // Likewise, except we're shifting to
// to the left by seven instead of eight.
byte_4 = (byte_3 & 0xFF00) >> 8 // We may have pushed into byte_3's buffer, so shift accordingly.

FLUSH(byte_2)
FLUSH(byte_3)

// Terms with coefficient r**2.

buffer = src1*src1
byte_3 += (buffer & 0x00FF)
byte_4 += ((buffer & 0xFF00) >> 8) + ((byte_3 & 0xFF00) >> 8)

FLUSH(byte_3)
FLUSH(byte_4)

buffer = src0*src2 // *2.
byte_3 += (buffer & 0x00FF) << 1.
byte_4 += ((byte_3 & 0xFF00) >> 8) + ((buffer & 0xFF00) >> 7)

FLUSH(byte_3)
FLUSH(byte_4)

// Terms with coefficient r**3.
byte_4 += (src0*src3) << 1 // Multiply by 2.
FLUSH(byte_4)

byte_4 += (src1*src2) << 1 // Multiply by 2.
FLUSH(byte_4)

/*
* Glue the pieces back together, and deliver the result.
*/


Square._SetBlock(1, byte_1 | (byte_2 << 8))
Square._SetBlock(2, byte_3 | (byte_4 << 8))

return Square

The simpler way to do squaring is just,
Square()
return src. Multiply (src)

and this is in fact what I have in pif_BigInt, because there's isn't really a nice way to simplify it that I'm aware of. When doing fixed-width stuff, there definitely are simplifications you can make. In doing stress tests with large numbers of squares (about 500,000) I found that the optimized way is about 36% faster.

Now, why so much focus on making squaring faster? Sure, it shows up a lot, but at first glance perhaps not enough to justify all this. The real reason is that general exponentiation (i.e., arbitrary natural number exponents) uses the exponentiation-by-squaring algorithm, so optimizations to squaring directly impact powers in general.
My GIAD for today, started about 6 hours ago.

I'm thinking some form of Ninja SSB styled combat or something. We'll see.

In response to Kozuma3
The lack of Eureka is still disturbing e.e.
Made some crates and bushes


I think I may have to redraw the bushes, since I accidentally made them super detailed compared to everything else :x
In response to D4RK3 54B3R
Your game is beautiful! What's the game play like?
In response to Calus CoRPS
Thanks :)

The game design is inspired by Casual Quest, Diablo 3, Hyper Light Drifter, and Zelda. Some strange mashup of those, I guess. I did post a few gifs of combat a while ago but they're kind of hard to find :[

Each ability slot has a pool of several selectable skills, like Diablo 3 or Guild Wars 2.
Combat is heavily inspired by Casual Quest and Hyper Light Drifter.
Ability Design is draws from Zelda, Guild Wars 2, and some Board games. There's going to be a heavy emphasis on the use of consumeable items and crafted potions, and many abilities will have strong synergies to one another but allow enough flexibility to allow you to play the character the way you want. For example, the guy above is of the Brigand class. You can play him as a sneaky stealthy ambusher, or as an agile ranged character, depending on which skills you choose. Despite the flexibility, each class will play in a distinctly different manner from all the others.

Level design is going to draw from Hyper Light Drifter and Zelda. Stages will not be as cramped as Zelda overall, and will feel more open like Hyper Light Drifter, but will be procedurally generated in a manner that is inspired by Zelda's dungeons. So rooms and corridors and secrets and traps and keys and puzzles. Puzzles are not going to be procedurally generated but will be procedurally placed.

Game will be multiplayer coop.
Page: 1 2 3 ... 172 173 174 175 176 ... 349 350 351