Baba is you topic

So, this is the topic for my game baba is you hardware, where i will be posting bugs and new features! It is intended to make this arcade project into the full game baba is you, not every rule and so, but just a mini version you can play on the fly. (please pretend the nintendo switch version doesnt exist, thanks!)

This is what i have so far:
Custom tilemap engine
Auto arranging tiles
Pushable tiles and walls (issue with pushable tiles despawning fixed)
Baba (is you)
Spritesheets

Link

https://makecode.com/_gUd9LziqV5Lp

Most spectacular and cool feature is of course the auto arranging tiles, here it is in its glory: (Its really simple but im really proud of it) (Also made walls pushable)
skillissuegemtree

Also a bug:
When trying to undo a action, the tilemap wont change to the preveus tilemap. I dont know why this happens. I have tried changing the list from my tile class to a list of default values, and then stringifying and parsing it, to no avail. Even storing the list and then setting it again doesnt work for some reason.

Code under engine.ts
namespace engine {
    export const canPush: string[] = ["box", "wall"]
    export const wall: string[] = []

    export let undos: any[][] = []
    export function makeUndo() {
        if (undos.length > 50) {
            undos.removeAt(0)
        }
        undos.push([direction, spriteMap.getSpritesTile(baba), spriteMap.currentTileMap])
//currentTileMap = new spriteMap.tile()[]
    }

    export function doUndo() {
        if (undos.length > 1) {
            let temp = undos.pop()
            if (temp) {
                let map = temp[2]
                let i = 0
                spriteMap.currentTileMap = map
                spriteMap.moveToTile(baba, temp[1])
                direction = temp[0]
            }
        }
    }
}
1 Like

Encountered another problem, this time even bigger:

I’d like to store all my images in a vtable like this.

    export let frames: any = {
        "entities": {
            "baba": getEntityImages(assets.image`baba`),
        },

        "tiles": {
            "tiles": {
                "box": [utilities.cropImage(assets.image`objects`, 0, 0, 1, 1, true)],
                "wall": splitTile(assets.image`tiles`, 0, 0),
                "test": splitTile(assets.image`tiles`, 0, 3),
                "grass": splitTile(assets.image`tiles`, 3, 0),
            },

            "text": {
                "baba": utilities.cropImage(assets.image`text`, 0, 0, 1, 1, true),
                "wall": utilities.cropImage(assets.image`text`, 1, 0, 1, 1, true),
                "box": utilities.cropImage(assets.image`text`, 2, 0, 1, 1, true),
                "grass": utilities.cropImage(assets.image`text`, 3, 0, 1, 1, true),
                "text": utilities.cropImage(assets.image`text`, 4, 0, 1, 1, true),
            },
        },

        "particles": {
            "skid": splitIntoImages(assets.image`particles`, 0, 0, 4, 1),
        }
    }

I also need to get it with variables like this:

        draw() {
            let img = imageLib.clearImage
            let id = this.id
            img = allThings[id][Math.clamp(0, allThings[id].length, this.imgid)] //Here
            let x = (this.tx - 1) * tileMapSizePix + (tileMapSizePix / 2)
            let y = (this.ty - 1) * tileMapSizePix + (tileMapSizePix / 2)
            image.screenImage().drawTransparentImage(img, x + this.xoff, y + this.yoff)
        }

(Allthings is just a reference for frames)
But when i run the game Frames is undefined. Also, the ordering issue still persists, where scripts run before the actual Frames vtable is made.

Help would really be appreciated!!
If you got an idea to store images in a similair manner, keep in mind that i also need a update function (that re-makes the list) for levels that have bigger tiles.
(Screen is black because it doesnt work)

Does anyone know why this happens? This is the typical way i store things. I did test it with normal strings, and it works fine. It seems to not work with images, do i perhaps have to use buffers?

let a : any = {aa:{bb:{cc:"hi"}}, ab:{bb:{cc:"hi2"}}}
b = "aa"
c = a[b]["bb"].cc
console.log(c)

I’m really desperate to revive this project, nothing seems to work. Perhaps this is a compiler bug?
Current game: https://makecode.com/_AJz655CT3Ha3

In this code:

    export let frames: any = {
        "entities": {
            "baba": getEntityImages(assets.image`baba`),
        },

        "tiles": {
            "tiles": {
                "box": [utilities.cropImage(assets.image`objects`, 0, 0, 1, 1, true)],
                "wall": splitTile(assets.image`tiles`, 0, 0),
                "test": splitTile(assets.image`tiles`, 0, 3),
                "grass": splitTile(assets.image`tiles`, 3, 0),
            },

            "text": {
                "baba": utilities.cropImage(assets.image`text`, 0, 0, 1, 1, true),
                "wall": utilities.cropImage(assets.image`text`, 1, 0, 1, 1, true),
                "box": utilities.cropImage(assets.image`text`, 2, 0, 1, 1, true),
                "grass": utilities.cropImage(assets.image`text`, 3, 0, 1, 1, true),
                "text": utilities.cropImage(assets.image`text`, 4, 0, 1, 1, true),
            },
        },

        "particles": {
            "skid": splitIntoImages(assets.image`particles`, 0, 0, 4, 1),
        }
    }
    console.log(frames.length)

It looks like you are treating frames as an array (when you print out length), but it is not an array. It’s an object. Object’s do not have a property called length, so it will return undefined if you try to print it out.

Also my guess is that you are accessing the frames variable before it’s had a chance to run. This isn’t a compiler bug, if you want the variable to be guaranteed to be assigned when this code runs then you should assign it inside a function and call that before the other code runs.

In other words, make sure you call imageLib.update() before you try and access imageLib.frames

I already actually tried that. I also used

Object.keys(quesArr).length

Which does the same. Workarounds for the win!
Perhaps the updated game version already fixed these things? I’m not sure. The errors all look the same, mostly something with findidx.

The findidx error really just means something is undefined when it shouldn’t be (terrible error message, I know).

I saw you calling the function in a different file; the ordering of which file executes first isn’t really guaranteed by the app. It’s best to call your function right above where you’re trying to access the variable.

… I give up. But, how would you approach this? How would you store all of these images and retreive them? I dont think the built in image storage is a option, its gonna be a big project with lots and lots of images.

If I needed to get a bunch of specific images, I would probably use an enum and a function:

enum TileKind {
    Ground,
    Wall,
    // etc.
}

function getTile(kind: TileKind) {
    switch (kind) {
        case TileKind.Ground: return assets.tile`ground`
        case TileKind.Wall: return assets.tile`wall`;
        // etc.
    }
}

This has a few advantages:

  1. Everything is handled by a function so you don’t need to worry about what order files are executed in (functions are always accessible)
  2. You aren’t declaring a top-level object so it doesn’t take up any memory until you actually fetch the tile
  3. All of the tiles are named in the enum so it’s impossible to make a spelling error or call something by the wrong name (the compiler will catch those mistakes)

Ok! Thanks! But i have more things than only tiles, do i have to make seperate enums and functions per type of image? Or do i have to just put alot of switches and arguments in the function?

Also ive tried this and while it does work, every frame you’re cropping and splitting those tiles again. 8 fps on pc. Then the issue still persists: i need to put all of those images in a list to avoid doing that, it defeats the whole purpose

Hi again,

Ive tracked it down to not the order of it being run, but rather how i defined it. Ill explain:

If i just define it as a any like this

  export let allEntities: any = {}

It will error with findidx. If i define it like this

export let allEntities:  { [key: string]: Image[][][] }  = {}

It will work fine. Now the question is, how do i properly define a list like frames?

Suprise!!! I was hard at work for the next version of the game. This time, the rule system is half-implemented. Progress was slower due to school. Press B to reload all rules. The system should be dynamic and should work with new words like “push”

Reloading rules is a bit laggy for hardware, i dont know how to make it faster

can you make a block version?

that would be impossible

blocks are very limited