PC [Project] Build a Computer in Terraria!

putianyi888

Terrarian
Hi, everyone! I've been working on this project for weeks, and recently since I saw the possibility that I could make it, I decided to post it to gather further ideas and suggestions.

Perhaps you don't understand what is a computer, or why I want to build a computer. I would explain at once.

I have seen many excellent mechanical works, like those giant hoiktronics by DicemanX and those minigames by TheRedStoneCrafter. But each complicated project has to be built from almost zero. A computer can handle some edited programmes. With a computer, one can build minigames or do calculations by simply programming.

I'm not updating this thread often. For all wiring schematics, world download and the latest progress on this project, please refer to https://github.com/putianyi889/Computer-in-Terraria

Structure of a Computer in Terraria

A computer in reality contains a CPU, an RAM, a hard disc and some i/o devices. In Terraria, things change a lot. First of all, there is no electricity so there is no such memory that loses data after blackout. What's more, there is no time delay during logical calculus, so register cannot be faster than RAM. In conclusion, a computer in terraria don't need to contain registers or a hard disc. Secondly, since a program is fixed once released, we can use ROM instead of RAM to store them. As I will show later, an ROM is much smaller than that of an RAM. Thirdly, there are a variety of i/o devices in Terraria, so I don't have to consider building them. All I need to do is to design a way for this computer to communicate with other devices.
Overall, a computer in terraria could only contain a CPU without registers, an ROM and an RAM.

How to transport data

To prevent wires from taking too much space, I use an important technique to transport multibit data through a single wire. There were posts of this technique before, and I'm just posting my design here. To understand this technique you may read this first.
239.png
240.png

241.png
242.png

Place A and place B are connected by a single yellow wire. Switching the lever at A will synchronize torchs at B with those at A, which means that the yellow wire carrys a 8-bit data. In my designs I mostly use the vertical version of this technique.

Current Progress and Some Notes

The following is my plan list and progress. Please feel free to ask any question. Any idea or suggestion would be appreciated.

(finished) RAM, ROM and Registers
ROM is used for coding. It can only be written by wiring. Registers stores variables. Each register can be read and write once per cycle. RAM stores variables that registers are to few to hold. Only one address in RAM can be read and write per cycle. Since communication between two registers is more convenient than that between two addresses in RAM, it's recommended to store most recently and frequently used variables in registers. The compact RAM design was created by @Programmatic .​

(in progress) 8-bit CPU
(finished) 8-bit ALU (Wikipedia)
ALU is an essential part of CPU. It receives two 8-bit operands denoted by A and B and performs 14 operations: A+B, A-B, A&B, A|B, A^B, A>B, A<B, A>=B, A<=B, A==B, A!=B, A>>B, A<<B, A>>>B. There are still 2 operations left.
(finished) Return Address Stack
In MIPS, there is a register $ra containing a return address. It's used in case of function invoking. However, an instruction address is at least 10 bit long so that a register cannot hold it. Based on the role $ra plays in MIPS, I designed an address stack specifically for $ra. Sending an address to $ra means to push the address into the stack, while obtaining an address from $ra means to pop the address from the top.
(finished) Machine language
A machine language is designed to match a CPU, while a CPU is designed to read the machine language.

My current design is based on 8 bit MIPS (wiki).
There are some explicit data registers. I haven't decided how many explicit registers there should be, but there could be no more than 16 of them.
There are some implicit data registers:
$ad is the current address of the RAM; (finished)
$va is the value corresponding to $ad; (finished)
$im stores an immediate number; (finished)
$op1 and $op2 are two operands of the ALU; (finished)
$ans is the result from the ALU; (finished)
$mu1 and $mu2 are two operands of the multiplier;
$muh and $mul are the higher 8 digits and lower 8 digits of the product from the multiplier;
$di1 and $di2 are two operands of the divider;
$diq is the quotient from the divider;
$dir is the residue from the divider.​
There are some implicit address registers:
$ra is the return address stack; (finished)
$addr is the last 10 bit of an instruction; (finished)
$PC is the current instruction address;
$nPC is the next instruction address; (finished)
$BTA denotes the branch-to address. (finished)​
A general instruction is opcode(4)+whatever(16). At the start of each cycle, $nPC sends its address to $PC and the current instruction can be read from the ROM. It also sends the address to $BTA in order to compute the next instruction address.

R-type instruction is opcode(4)+rd(4)+funct(4)+rt(4)+rs(4). Data flow: $rs to $op1, $rt to $op2, ALUf set to funct, $ans to $rd, add 1 to $BTA, $BTA to $nPC. There are 16 different R-type instructions depending on funct(4).

J-type instruction is opcode(4)+jext(2)+address(14). There are 4 different J-type instructions depending on jext(2):
j: jump. Data flow: $addr to $nPC.
jal: jump and link. Data flow: add 1 to $BTA, $BTA to $ra, $addr to $nPC.
jr: jump register. Data flow: $ra to $nPC.
jalr: jump register and link. Data flow: $ra to $nPC, add 1 to $BTA, $BTA to $ra.​
I-type instruction is opcode(4)+imm(8)+rt(4)+rs(4).
beq: branch equal. Data flow: $rs to $op1, $rt to $op2, set ALUf to ==, add 1 (if $ans==0$) or $im (if $ans==1) to $BTA, $BTA to $nPC.
bne: branch not equal. Data flow: $rs to $op1, $rt to $op2, set ALUf to !=, add 1 (if $ans==0$) or $im (if $ans==1) to $BTA, $BTA to $nPC.
ble: branch less equal. Data flow: $rs to $op1, $rt to $op2, set ALUf to <=, add 1 (if $ans==0$) or $im (if $ans==1) to $BTA, $BTA to $nPC.
bgt: branch greater. Data flow: $rs to $op1, $rt to $op2, set ALUf to >, add 1 (if $ans==0$) or $im (if $ans==1) to $BTA, $BTA to $nPC.
sb: save byte. Data flow: $rs to $op1, $im to $op2, set ALUf to +, $ans to $ad, $rt to $va, RAM write, add 1 to $BTA, $BTA to $nPC.
lb: load byte. Data flow: $rs to $op1, $im to $op2, set ALUf to +, $ans to $ad, RAM read, $va to $rt, add 1 to $BTA, $BTA to $nPC.
addi: add immediate. Data flow: $rs to $op1, $im to $op2, set ALUf to +, $ans to $rt, add 1 to $BTA, $BTA to $nPC.
slti: smaller than immediate. Data flow: $rs to $op1, $im to $op2, set ALUf to <, $ans to $rt, add 1 to $BTA, $BTA to $nPC.
andi: and immediate. Data flow: $rs to $op1, $im to $op2, set ALUf to &, $ans to $rt, add 1 to $BTA, $BTA to $nPC.
ori: or immediate. Data flow: $rs to $op1, $im to $op2, set ALUf to |, $ans to $rt, add 1 to $BTA, $BTA to $nPC.
xori: xor immediate. Data flow: $rs to $op1, $im to $op2, set ALUf to ^, $ans to $rt, add 1 to $BTA, $BTA to $nPC.
R-type-ext instruction is opcode(4)+rd(4)+ru(4)+rt(4)+rs(4).
mult: multiply. Data flow: $rs to $mu1, $rt to $mu2, activate multiplier, $muh to $rd, $mul to $ru.
div: divide. Data flow: $rs to $div1, $rt to $div2, activate divider, $diq to $rd, $dir to $ru.
There are 16 different opcodes. R-type takes 1. J-type takes 1. I-type takes 11. R-type-ext takes 2. There is an opcode left for drivers, e.g. display.​
(in progress) Control Unit and Data Path
The control unit reads an instruction and activates every part of CPU at a proper time, helping them work together.
(in progress) Multiplier and Divider
@ekinator has designed them, but I want to make them more compact. I would still use his design whenever the compact versions haven't come out.
Measuring the Lag
@DRKV made me aware of the lag caused by trying to perform a great many operations in a tick. So before I continue building, I have to figure out how the lag works and try to predict the lag, so that I could know which kind of circuit is faster.

I placed a massive number (about 80*1117=89360) of torches in my test world and wired them to a conveyor belt engine which activates once per tick. Then I use my own stopwatch to measure the period of an in-game 5-second timer. While the engine is working, the period of a 5-second timer increases to around 18~20 seconds, depending on the lighting mode and video quality but not depending on frame skip or multicore lighting. Since the video settings don't make a big difference, I guess the lag is caused mainly by turning on or off the torches.

The lag also depends on hardware.
Reference

David Money Harris & Sarah L. Harris, Digital Design and Computer Architecture
 
Last edited:
Yay! Finally someone's making a fully blown logic gate computer. :happy: If you need anything, I would be very glad to help!

ALU is an essential part of CPU. It receives two 8-bit operands denoted by A and B, and a function input F telling which operation to perform. Its output is F(A,B). Currently I decide there should be 8 operations: A+B, A-B, A&B, A|B, A^B, A<B, A==B and A>B. And F should be 3-bit.
So, how are you doing the compare exactly? Traditionally you just have one compare instruction that does a subtraction, sets the appropriate flags, but doesn't save the result.

(not started) Design a machine language and build other parts of the CPU
A machine language is designed to match a CPU, while a CPU is designed to read the machine language. I have some ideas, but I could not say it's a start, because there are so many things to consider. I appreciate any suggestions on this issue.
Well, I'd say go with a register memory architecture instead of load/store. Not much point in differentiating the two, since they are pretty much the same thing in terraria. Also, I'd really like to finally see a proper von Neumann computer instead of Harvard like all the rest of the video game based machines.

I haven't decided whether ALU should include shift operations, so just let it alone now.
Most definitely yes. Shift and rotate are both very useful.

They are unnecessary because these two operations can be programmed using addition, subtraction and shifting.
Well, yeah I guess. Thou I'd say it would still be rather nice if you had dedicated hardware for multiplication. Space isn't exactly at a premium as I gather... Then you could do multiplication in a single clock cycle. (Or more depending on how your fetch and decode works.)

So anyway, good luck with your build. Maybe post some nice pictures of the parts you finished?
EDIT: Oh never mind, you already addressed that...
 
Last edited:
If you need anything, I would be very glad to help!
Thanks for your support! :D
So, how are you doing the compare exactly?
Since all numbers are signed, just do subtraction and take the digit denoting the sign.
Well, I'd say go with a register memory architecture instead of load/store. Not much point in differentiating the two, since they are pretty much the same thing in terraria.
That's just what I mentioned within Structure of a Computer in Terraria
Thou I'd say it would still be rather nice if you had dedicated hardware for multiplication.
Actually I have built a multiplier (showcase in Chinese) but I'd rather build a programmed ROM instead XD. There is a method to build an engine with unlimited frequency, so it doesn't matter if calculation takes too many cycles.
 
Last edited:
Most of that stuff is just going right over my head lol. `:confused:

Sounds like quite a challenge! I can't wait to see how it turns out!
 
That's just what I mentioned within Structure of a Computer in Terraria
Whoops, sorry. I totally didn't read that. I was a bit too excited. :D

Actually I have built a multiplier (showcase in Chinese) but I'd rather build a programmed ROM instead XD. I have the technic to build an engine with unlimited frequency, so it doesn't matter if calculation takes too many cycles. I will post that technic once I have time.
Yeah, so theoretically that could work, but sending out many individual signals, and poking many logic gates many times, seems to be kinda hard on processing time. Like, if you look at my elementary CA here: https://forums.terraria.org/index.php?threads/showcase-element-elementary-cellular-automaton.71319/ It has a 60act/s dummy engine, but it definitely does not run at 60 rows per second. Adding more engines would probably just slow it down due to all the lag. So having to read the instructions from ROM and decoding all of them might get unbearably slow.
But I am not exactly sure about this, but you know, just a word of warning.
 
Adding more engines would probably just slow it down due to all the lag. So having to read the instructions from ROM and decoding all of them might get unbearably slow.
But I am not exactly sure about this, but you know, just a word of warning.
Sure. After all, the mechanism is run by a real computer, so there is a limitation of its operating speed. I guess it's a restriction on the number of logical gates operating in one tick. However, whether adding a multiplier can increase the computer's speed depends on how the ALU works. My current design is that ALU performs all operations at the same time and chooses the result needed. In this case, adding more functions to ALU slows the speed. If we want to increase the speed by adding more functions, the ALU should first decide to which circuit the operands should be sent, and I have to redesign from zero. Considering that adding a multiplier may increase multiplication speed by 1/2 or 2/3, I prefer to continue my current decision and leave the faster ALU until slow speed becomes a main problem of this computer.

Thanks for making me realize the speed limitation in game! :D
[doublepost=1541424057,1541266968][/doublepost]

(Outdated, please refer to the main post)
Here is my ALU kernel
Capture 2018-11-05 12_38_12.png
Capture 2018-11-05 12_38_18.png


There are 6 inputs and 4 outputs. Input A and B are two operands. I use an important technique to send a multibit signal by a single wire.

Input C starts the conversion of signals from A and B into 16 seperate wires. Input D changes A to ~A, while E changes B to ~B. Input F adds the sum of A and B by one, which is used to do subtraction, because A-B=A+~B+1.

Output G is the sum or difference. Output H is A&B while output I is A^B. Output J is A==B. Note that G, H and I use the technique above. There is no "OR" because A|B=~(~A&~B).

To make the ALU work, we just need to add some control circuits.
[doublepost=1541424347][/doublepost]WTF is the post merging feature? The posts are completely irrelevant. Anyone knows how to show them seperately?
 
Last edited:
Hi, everyone! I've been working on this project for weeks, and recently since I saw the possibility that I could make it, I decided to post it to gather further ideas and suggestions.

Perhaps you don't understand what is a computer, or why I want to build a computer. I would explain at once.

I have seen many excellent mechanical works, like those giant hoiktronics by DicemanX and those minigames by TheRedStoneCrafter. But each complicated project has to be built from almost zero. A computer can handle some edited programmes. With a computer, one can build minigames or do calculations by simply programming.

Structure of a Computer in Terraria

A computer in reality contains a CPU, an RAM, a hard disc and some i/o devices. In Terraria, things change a lot. First of all, there is no electricity so there is no such memory that loses data after blackout. What's more, there is no time delay during logical calculus, so register cannot be faster than RAM. In conclusion, a computer in terraria don't need to contain registers or a hard disc. Secondly, since a program is fixed once released, we can use ROM instead of RAM to store them. As I will show later, an ROM is much smaller than that of an RAM. Thirdly, there are a variety of i/o devices in Terraria, so I don't have to consider building them. All I need to do is to design a way for this computer to communicate with other devices.
Overall, a computer in terraria could only contain a CPU without registers, an ROM and an RAM.

Current Progress and Some Notes

The following is my plan list and progress. Please feel free to ask any question. Any idea or suggestion would be appreciated.

(finished) RAM

(finished, will be posted later) ROM

(in progress) 8-bit CPU
(in progress) 8-bit ALU (Wikipedia)
ALU is an essential part of CPU. It receives two 8-bit operands denoted by A and B, and a function input F telling which operation to perform. Its output is F(A,B). Currently I decide there should be 8 operations: A+B, A-B, A&B, A|B, A^B, A<B, A==B and A>B. And F should be 3-bit.
Note1: "&" means "AND", "|" means "OR", "^" means "XOR"
Note2: One can use 0-A to get -A and use A^11111111 to get NOT A.
Note3: I know there is someone who has built an ALU. But I just think that's too large. My ALU is nearly finished, and I guess a finished one should take no more than 2/3 of my 1304*744 window.​
(not started) Design a machine language and build other parts of the CPU
A machine language is designed to match a CPU, while a CPU is designed to read the machine language. I have some ideas, but I could not say it's a start, because there are so many things to consider. I appreciate any suggestions on this issue.​
(in progress) Shifter (Wikipedia)
I haven't decided whether ALU should include shift operations, so just let it alone now.​
(unnecessary) Multiplier (Wikipedia) and Divider
They are unnecessary because these two operations can be programmed using addition, subtraction and shifting.
Measuring the Lag
@DRKV made me aware of the lag caused by trying to perform a great many operations in a tick. So before I continue building, I have to figure out how the lag works and try to predict the lag, so that I could know which kind of circuit is faster.

I placed a massive number (about 80*1117=89360) of torches in my test world and wired them to a conveyor belt engine which activates once per tick. Then I use my own stopwatch to measure the period of an in-game 5-second timer. While the engine is working, the period of a 5-second timer increases to around 18~20 seconds, depending on the lighting mode and video quality but not depending on frame skip or multicore lighting. Since the video settings don't make a big difference, I guess the lag is caused mainly by turning on or off the torches.

I'll do further research on this topic. Because the lag may depend on hardwares, I hope someone having a PC could help me find how hardwares affect the lag.
Reference

David Money Harris & Sarah L. Harris, Digital Design and Computer Architecture
I thought about this a while back. Glad to see that someone’s actually making it!
 
`:)Hi, friend! I will always support you! That's a very difficult task, but my level is not enough to help:(
 
Try making the equivalent of an intel 4004, the first microprocessor. Only problem is, you can’t get the frequency over 60hz, so it will be really underpowered. Or you could just make the die as big as a large world.
Edit: You can only make it 0.00000006ghz!
 
Try making the equivalent of an intel 4004, the first microprocessor.
You could probably do that, but in a lot of ways we can also do better. The 4004 uses a classic load/store architecture, but in terraria there is no need for that. Registers and memory are effectively the same thing here.
The 4004 actually has a separate accumulator, which is pretty much the only register that can do anything exciting. This means you would have to constantly move your data around, which in terraria has quite a large performance cost.
Also it uses 4bit data words...
Only problem is, you can’t get the frequency over 60hz, so it will be really underpowered. Or you could just make the die as big as a large world.
Why? There is nothing stopping you from just slapping a few more dummy engines on the clk line. Actually, the only limit to the computers clock speed should be how fast the "host" processor can run terraria wiring.
 
So, whats the limit on the refreshing rate of wiring? Is it equivalent to the refresh rate of your monitor?
There is no refreshing rate for wiring. Every time a physical power source (power sources except logic gates) activates, it triggers a so-called refreshing of wiring (reference). Since there is no limit on the number of activating physical power sources in a tick (reference), there is no limit on refreshing rate of wiring.
 
I've attempted making a computer in Terraria a few times in the past, but I've usually ended up hitting some roadblock that led me to restarting multiple times. While I probably won't be attempting to make a computer again for a while (I haven't played Terraria in months), I wish you the best of luck and look forward to seeing what you come up with.

Here's some components I had come up with when I was working on the project:
RAM: https://forums.terraria.org/index.p...ign-and-update-on-the-computer-project.63658/
Hard Drive: https://forums.terraria.org/index.php?threads/compact-hard-drive.56163/
ALU: https://forums.terraria.org/index.php?threads/16-bit-alu.57596/
Tutorial series showcasing some fundamental wiring devices: https://forums.terraria.org/index.php?threads/a-wiring-tip-a-day.54933/
Part 2: https://forums.terraria.org/index.php?threads/a-wiring-tip-a-day-week-2.55220/
 
I've attempted making a computer in Terraria a few times in the past, but I've usually ended up hitting some roadblock that led me to restarting multiple times. While I probably won't be attempting to make a computer again for a while (I haven't played Terraria in months), I wish you the best of luck and look forward to seeing what you come up with.

Here's some components I had come up with when I was working on the project:
RAM: https://forums.terraria.org/index.p...ign-and-update-on-the-computer-project.63658/
Hard Drive: https://forums.terraria.org/index.php?threads/compact-hard-drive.56163/
ALU: https://forums.terraria.org/index.php?threads/16-bit-alu.57596/
Tutorial series showcasing some fundamental wiring devices: https://forums.terraria.org/index.php?threads/a-wiring-tip-a-day.54933/
Part 2: https://forums.terraria.org/index.php?threads/a-wiring-tip-a-day-week-2.55220/

Thanks for replying! It's happy to see someone did something before. Your RAM works quite differently from mine and I will consider which one is better. I have gone through your videos on YouTube and your wiring tips. In your ALU, you made shift operations but each of them shifts only one bit. Is it enough? I'm sorry if I missed anything in your videos or posts.

Also, could you please tell what roadblocks you hit? I'm afraid I'm running into one of them.
 
Thanks for replying! It's happy to see someone did something before. Your RAM works quite differently from mine and I will consider which one is better. I have gone through your videos on YouTube and your wiring tips. In your ALU, you made shift operations but each of them shifts only one bit. Is it enough? I'm sorry if I missed anything in your videos or posts.

Also, could you please tell what roadblocks you hit? I'm afraid I'm running into one of them.

Regarding the one-bit shift, making a multi-bit shift takes up a lot of extra space, and such an operation would be rarely used. To shift multiple bits, it would be better just to trigger a single shift operation multiple times.
Regarding roadblocks, the main problem I ran into was that I would have the two main components (RAM and ALU) working fine on their own, but I couldn't come up with a working control unit that could read code from RAM, interpret it, transfer data to the ALU, and then execute the proper operations. Unlike the RAM and ALU, which can each be made just by copying and pasting a few small parts, the control unit is far more complicated, and I just couldn't motivate myself to take the time to make something so complex, especially given college and stuff like that.
 
but I couldn't come up with a working control unit that could read code from RAM, interpret it, transfer data to the ALU, and then execute the proper operations.
I have the same problem. To make things easier I use a machine language far different from those in reality. I have updated it in my main post.
Regarding the one-bit shift, making a multi-bit shift takes up a lot of extra space, and such an operation would be rarely used. To shift multiple bits, it would be better just to trigger a single shift operation multiple times.
Thanks for the explanation. I don't major in CS so I don't have much experience on how often the instructions are used.
 
Last edited:
1024*20bit ROM & 256*8bit RAM. Each bit of ROM takes 1*2 space. Each bit of RAM takes 1.5*6 space. Each column is associated with an address.
Note: New RAM design within https://forums.terraria.org/index.p...mputer-in-terraria.73927/page-2&#post-1666486

Capture 2018-11-24 23_57_07.png


16*8bit registers. Each register can be read and write once per cycle. Activating the top left logic gate of a register starts the writing process while activating the top right logic gate starts the reading process.
Capture 2018-11-25 11_07_31.png
 
Last edited:
1024*20bit ROM & 256*8bit RAM. Each bit of ROM takes 1*2 space. Each bit of RAM takes 1.5*6 space. Each column is associated to an address.View attachment 213819

16*8bit registers. Each register can be read and write once per cycle. Activating the top left logic gate of a register starts writing process, while activating the top right logic gate starts reading process.
View attachment 213820
Some day, I'll understand what you just said. What are you going to do then?
 
Back
Top Bottom