Welcome to johnbintz.com

Escaped Chasm on Linux

Aug 19, 2019

As part of my Undertale stream I want to play Escaped Chasm and, before I drop to one of the old Windows 10 installs on one of my laptops, I want to see what’s involved in getting it running on Linux. Turns out it’s super easy and the answer to running it is not WINE, it’s Node.js:

tl;dr

# install node 10.0.0 or greater, i like nvm for this
nvm install 10
nvm use 10
cd <path to unzipped folder with Escaped Chasm.exe>
# install NW.js globally
npm i -g nw
cd www
# somewhere in the game a capital-F Fonts is used
# but we're on a case sensitive filesystem, so...
ln -sf fonts Fonts
cd ..

# run the game
nw .

(if you use this approach, install nvm.)

It looks like whatever version of RPG Maker Temmie used to export the game uses NW.js to make a cross-platform export (and exports the game code to JavaScript? I don’t know anything about RPG Maker code internals, maybe it’s all JS under the hood). This may even work for other non-Linux released RPG Maker games, though I haven’t tested. But I think if you see a package.json file and an nw.dll file in the root of the game, then it’s likely this method will work.

Godot Learning - Part 8

Aug 17, 2019

YSort!

Success! I got my player to walk behind the rabbit by placing both in a YSort:

But I have to make sure everything map-related goes into the YSort. My Exit Nodes were outside the YSort, so when I warped back into the larger first Map, I ended up in a weird spot. Also, moving all of the input logic to Main and pushing down events to Map and such is the way to go.

Next is making my TileMaps be the kind where the player can walk “behind” them.

Android Export

I got the game to export to Android, as I already had the Android environment installed for React Native and NativeScript-Vue compilation:

I hooked up a USB controller via an OTG cable and got the game to react to inputs, but, as expected, the YAML data didn’t work, so I’ll need to hook up a preflight script to covert YAML to JSON and use the JSON loader on Android, or just use JSON everywhere and run a watcher to convert YAML on-the-fly while I work.

Godot Learning - Part 7

Aug 15, 2019

YSort and 2d RPG games

I made a pixel art in Krita:

Then I put him in my game:

Then I walked behind him:

Oops.

My structure of the game looks like this, because I thought having Player outside of Map and not repeated in all the maps would make things easier:

  • Main
    • Map
      • Rabbit
    • Player

But it should look like this, and I’ll have to do more management of Player within maps when maps change:

  • Main
    • Map

My idea of centralizing all player input to Main and pushing down movement events to Player may be the direction I go for restructuring this…stay tuned.

Godot Learning - Part 6

Aug 12, 2019

Odds and Ends

  • If you want to make a factory class method, you can’t use new in a static method:

    class_name Kitten
    
    static func forCharacter(char):
      var kitten = new()
      kitten.setupCharacter(char)
      return kitten
    

    Instead, load the file from res:// and run new from that. This is to get around multithreading issues it seems:

    class_name Kitten
    
    static func forCharacter(char):
      var kitten = load('res://classes/Kittens.gd').new()
      kitten.setupCharacter(char)
      return kitten
    
  • I hate making up/down/left/right if blocks for movement:

    const MOVES = [
      ["ui_down", "y", WALK_SPEED],
      ["ui_up", "y", -WALK_SPEED],
      ["ui_left", "x", -WALK_SPEED],
      ["ui_right", "x", +WALK_SPEED],
    ]
    
    func _process(delta):
      var vector = Vector2(0,0)
      for move in MOVES:
        if Input.is_action_pressed(move[0]):
          vector[move[1]] += move[2]
    

Making Pixel Art

Krita is my art tool of choice anyway, so let’s see what the Internets have to say about using it for stills and animations:

  • https://www.youtube.com/watch?v=aaRzNTCanIQ
    • The newest video I could find
    • Modern Krita comes with a Pixel Art brush to align the pointer with the grid
    • Fill Bucket
      • Threshold 1, Grow Selection 0, Feathering 0
    • Disable Antialiasing on selecton tools
    • Subwindows for new views
    • Transform
      • Nearest Neighbor
    • Use wraparound (w) for tiling backgrounds
  • https://www.youtube.com/watch?v=ebF1pIxLpnU
    • Use Alpha Lock to make shading easier
    • Emulate antialiasing to make transitions between colors smoother
    • I need to get better about mirroring the canvas to check symmetry…

Godot Learning - Part 5

Aug 05, 2019

Dialogue Boxes Part 2

  • Use a combination of Input.is_action_just_released and !Input.is_action_pressed with ui_accept to find out if interaction should continue. Rough pseudocode logic:

    var stopInteracting = false
    
    # only continue if everything is ok
    if isInteracting and isAllowedToContinueInteracting and Input.is_action_just_released("ui_accept"):
      emit_signal("continue_interaction", "next")
      isAllowedToContinueInteracting = false
    
    # have to release the key to continue
    if !Input.is_action_pressed("ui_accept"):
      isAllowedToContinueInteracting = true
    
    if canMove && !isInteracting:
      if interactTarget && Input.is_action_just_released("ui_accept"):
        isInteracting = true
        emit_signal("start_interaction", self)
        isAllowedToContinueInteracting = false
    
    if stopInteracting:
      isInteracting = false
      stopInteracting = false
    

    This gets a little weird with a menu system, though, as I want the DialogBox to control input. I may move Player and DialogBox Input handling up to Main and send it down to the appropriate objects based on game state.

  • setget doesn’t fire setters and getters if you are setting or getting the value in the same script, so this does not fire the setter:

    # CoolCat.gd
    
    var cat setget set_cat
    
    func set_cat(newCat):
      cat = newCat
      do_cat_things()
    
    func _process():
      if somethingHappens:
        cat = "meow" # do_cat_things is not called.