In the context of a computer game (where each player or the game board etc. holds a "state") rather than having an array of variables or storing small[ish] values (like 0 or 1 or 2 etc) in separate variables (like u32) we could treat one variable as many by turning that single variable into a multi-slot representation through the use of modulo arithmetic and exponentiation.
Hand writing memory in WebAssembly is possible. But if we are only writing in Rust and treating Wasm as a compilation target could the following idea be implemented as a design pattern for higher level programming i.e. Rust? Or, is the compiler so smart that this idea is redundant (after all of the wonderful optimisations and magic that compilers perform)?
The u32 variable in Rust can hold a value within the range of 0 to 2147483648. We essentially have access to 10 separate slots. If we initialise the variable with 1000000000 (first digit set to 1) then any of the remaining 9 slots can each hold a separate value of 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9.
Slot [10| 9| 8| 7| 6| 5| 4| 3| 2| 1]
Value[ 1| 0| 0| 0| 0| 0| 0| 0| 0| 0]
The following psuedo code allows us to access each of the individual slots of the _value, by specifying the slot's _position and the _size of the slot.
((_value % (10 ** _position)) - (_value % (10 ** (_position - _size)))) / (10 ** (_position - _size));
In this example, lets just make the size of the slot 1. For example let's just access any one of the 9 individual slots as a single digit. For example, in order to do this we can go ahead and rewrite this psuedo code with _size statically set to 1.
((_value % (10 ** _position)) - (_value % (10 ** (_position - 1)))) / (10 ** (_position - 1));
The following code demonstrates how we can access each of the 9 slots.
Please note:
_valueis set to1987654321for this example_sizeis set to1for this example_positionindicates which Slot we are accessing
Slot number we are accessing [10| 9| 8| 7| 6| 5| 4| 3| 2| 1]
Value stored in that slot [ 1| 9| 8| 7| 6| 5| 4| 3| 2| 1]
(_value % (10_u32.pow(_position)) - (_value % (10_u32.pow(_position - _size)))) / 10_u32.pow(_position - _size)
If _position is 1, this code returns 1
If _position is 2, this code returns 2
etc.
It is super easy to flush a value back to 0. For example we can set slot 1 to 0 like this.
Where _position is 1
_value = _value - ((_value % (10_u32.pow(_position))) - (_value % (10_u32.pow(_position - _size))));
Returns a new state of 1987654320
After we have zero'd out a slot, it is also super easy to explicitly insert/update one of the slots with a new single digit.
For example, where _single_value is 9 and _position is 1.
_value + _single_value * (10_u32.pow(_position - 1));
Returns a new state of 1987654329
There needs to be some static code that can validate _position, _value and the overall state, for safety. This code would be trivial and would/could ship as part of Wasm binary executable with fixed static values.
It is hoped that there is a sufficient trade-off between the computation required to perform the arithmetic and the amount of memory that would be saved. There may be other applications for this, other than remote multiplayer games or where perhaps game state has to be sent across the network quickly etc.
I would really appreciate feedback in relation to how this would compile in terms of WebAssebly memory and whether this idea could become a design pattern for building memory efficient applications where the final code is a compilation target. For example, is this useful in WebAssembly where (whilst you can write wat) there is a strong chance that a higher level language like Rust will create the wat, wasm automatically (in this case we have less control over memory and so hopefully this design pattern will be a cool trick in our toolboxes).
Please leave a comment below if you have any suggestions or ideas on how this could be of benefit to something you are working on. I am very happy to perform more research, development and testing if this will be of use to you. For example can a Wasm executable of the logic in this idea be stored on CDN as accessed like a library/service. With only the game state needing to be stored locally? Open to all ideas.
Thanks for reading :)