I made a text renderer for Construct 3

3
skymen's avatar
skymen
  • 18 May, 2019
  • 1,041 words
  • ~4-7 mins
  • 1,561 visits
  • 1 favourites

Hey, new post.

Today, on the french Construct Community, this message was posted:

The server recently started organizing small very short contests with very weird themes where anyone can join, and the winner gets to win a few Steam Keys.

The concept is nice, but I lacked time most of the time, so I never participated. Today, though, I had some time and the theme caught my attention.

The game must only show characters.

Now I'm familiar with that kind of text based fun. I do tons of stuff using text, and especially when I'm working on projects where all I have as a visual output is a console.

For example, a few years back, a relative and I wrote a flappy bird game in Pascal. The hook though was that Pascal doesn't support getting input and output at the same time, so we had to make two programs, one that would take input, and write it to a text file, and another one that would read the text file for input, and would print the game on the console.

Last year, I wrote an console based adventure engine where you could easily write branching paths, dialogue and choices to progress in the story. I did that because I was bored during school assignements, and a friend and I added short stories to our weekly assignements for the teacher to play after checking our submissions.

Anyway, I love these kind of challenges, so I thought I might give it a spin again.

The process

I didn't know what kind of game to make at first. I thought about remaking that flappy bird game. Then I thought about just making an infinite runner.

I decided that I'd just start working on the text engine and then I'd figure out what game I wanted to make.

Then it hit me: What if instead of making a whole engine from scratch inside of construct, I just made a thing that would render characters on top of sprites, and then use Construct's features for the game.

First, a cloud

I created a cloud as a first test sprite, and placed it on the layout, under the text renderer. I also created a new family "CustomDraw" and put the cloud in it.

Hey it's a start. I used Spritefont because the characters have a known size, so it's easier to know where to place them.

Now I want to loop through every character spot on the screen and determine what to draw there.

Since the objects are hidden, I can't use the animations or visibility options directly, so I had to write my own.

I just added a "visible" boolean and a "textOutput" string to the family.

You'll notice that huge condition I used:

That's to allow for scrolling. If the text object is on a layer that doesn't scroll, I need to convert a position on its layer to a position on the game layer where the scrolling happens. This formula allows me to do that.

The condition block itself allows me to pick the objects that are on the spot I'm currently at.

Once the objects are picked, I need to loop through them.

I loop through them ordered by ZIndex, to respect Construct's Z ordering, and draw the character I want on that spot. If a sprite doesn't have a character assigned to that spot, the lower object will stay showed there. It's a very rudimentary form of alpha value. What counts as an empty character is the empty string and a space character.

The animation system

This is the textOutput string for the player:

 ,,
 ..
 ( -)
 ||
*

 ,,
 ..
 ( -)
 /\

You'll notice it's drawn twice. That's because I used newline & "*" & newline as a frame delimiter. So the renderer will chose the frame based on that delimiter and what real frame it is on. That allows me to still use the built in animation system from Construct and have my system work on top of it.

Then to determine what char I need, I calculate the offset from the object's top left bounding box point to the current position, and divide that by 16 to get the position in characters. Then I just consider 1 char to be 1 unit, and use tokenat to get the right line then the right character to draw.

The player

I decided to make a platformer because it was the easiest game to make in Construct, and I was really only interested in making my renderer.

The player is mostly written like any platformer player.

Only thing noteworthy is that since that the renderer is bound to 16*16 blocks, scrolling and objects had to respect that as well. So I had to snap the player and every other object to a 16*16 grid at all times.

However, moving an object with platformer behavior like that is a bad idea, so I had to make the platformer part separately and pin the player to it. That also allowed me to have collisions done separately. It essentially works exactly as if you had separated player animations from player collider.

Last word

That's it. Once the renderer was done, I totally lost interest in the project. I still wanted to submit it to the contest and show it around, so I had to make a level, but it's the simplest level I made for a game, probably ever.

I wrote a spike behavior to have any kind of challenge, but as soon as I started working on enemies, I stopped wanting to work on this anymore, so I scrapped them, pushed a build and submitted it.

You can play it here btw: textplatformer.surge.sh

The renderer could be greatly improved though. It doesn't support rotation at the moment, and using the BBCode tags in Construct 3, I could easily add colors or even character animations. But nah, I'm done with this. If any of you want to build on this and make a real game, be my guest. The source of the project is on the Construct Community Discord's uploads channel : discord.gg/kGfBDXN

Subscribe

Get emailed when there are new posts!

  • 2 Comments

  • Order by
Want to leave a comment? Login or Register an account!
  • Great design. thx, i was very instuctive!

  • NIce post, great to understand the background and motivation for doing this cool little project.